Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd88976c

Browse files
committed
Use a separate memory context for GIN scan keys.
It was getting tedious to track and release all the different things thatform a scan key. We were leaking at least the queryCategories array, andpossibly more, on a rescan. That was visible if a GIN index was used in anested loop join. This also protects from leaks in extractQuery method.No backpatching, given the lack of complaints from the field. Maybe later,after this has received more field testing.
1 parent57fe246 commitd88976c

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

‎src/backend/access/gin/ginget.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key)
497497
}
498498
/* i is now the last required entry. */
499499

500-
MemoryContextSwitchTo(oldCtx);
500+
MemoryContextSwitchTo(so->keyCtx);
501501

502502
key->nrequired=i+1;
503503
key->nadditional=key->nentries-key->nrequired;
@@ -515,11 +515,14 @@ startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key)
515515
}
516516
else
517517
{
518+
MemoryContextSwitchTo(so->keyCtx);
519+
518520
key->nrequired=1;
519521
key->nadditional=0;
520522
key->requiredEntries=palloc(1*sizeof(GinScanEntry));
521523
key->requiredEntries[0]=key->scanEntry[0];
522524
}
525+
MemoryContextSwitchTo(oldCtx);
523526
}
524527

525528
staticvoid

‎src/backend/access/gin/ginscan.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ ginbeginscan(PG_FUNCTION_ARGS)
4444
ALLOCSET_DEFAULT_MINSIZE,
4545
ALLOCSET_DEFAULT_INITSIZE,
4646
ALLOCSET_DEFAULT_MAXSIZE);
47+
so->keyCtx=AllocSetContextCreate(CurrentMemoryContext,
48+
"Gin scan key context",
49+
ALLOCSET_DEFAULT_MINSIZE,
50+
ALLOCSET_DEFAULT_INITSIZE,
51+
ALLOCSET_DEFAULT_MAXSIZE);
4752
initGinState(&so->ginstate,scan->indexRelation);
4853

4954
scan->opaque=so;
@@ -227,6 +232,9 @@ ginFillScanKey(GinScanOpaque so, OffsetNumber attnum,
227232
}
228233
}
229234

235+
/*
236+
* Release current scan keys, if any.
237+
*/
230238
void
231239
ginFreeScanKeys(GinScanOpaqueso)
232240
{
@@ -235,38 +243,22 @@ ginFreeScanKeys(GinScanOpaque so)
235243
if (so->keys==NULL)
236244
return;
237245

238-
for (i=0;i<so->nkeys;i++)
239-
{
240-
GinScanKeykey=so->keys+i;
241-
242-
pfree(key->scanEntry);
243-
pfree(key->entryRes);
244-
if (key->requiredEntries)
245-
pfree(key->requiredEntries);
246-
if (key->additionalEntries)
247-
pfree(key->additionalEntries);
248-
}
249-
250-
pfree(so->keys);
251-
so->keys=NULL;
252-
so->nkeys=0;
253-
254246
for (i=0;i<so->totalentries;i++)
255247
{
256248
GinScanEntryentry=so->entries[i];
257249

258250
if (entry->buffer!=InvalidBuffer)
259251
ReleaseBuffer(entry->buffer);
260-
if (entry->list)
261-
pfree(entry->list);
262252
if (entry->matchIterator)
263253
tbm_end_iterate(entry->matchIterator);
264254
if (entry->matchBitmap)
265255
tbm_free(entry->matchBitmap);
266-
pfree(entry);
267256
}
268257

269-
pfree(so->entries);
258+
MemoryContextResetAndDeleteChildren(so->keyCtx);
259+
260+
so->keys=NULL;
261+
so->nkeys=0;
270262
so->entries=NULL;
271263
so->totalentries=0;
272264
}
@@ -278,6 +270,14 @@ ginNewScanKey(IndexScanDesc scan)
278270
GinScanOpaqueso= (GinScanOpaque)scan->opaque;
279271
inti;
280272
boolhasNullQuery= false;
273+
MemoryContextoldCtx;
274+
275+
/*
276+
* Allocate all the scan key information in the key context. (If
277+
* extractQuery leaks anything there, it won't be reset until the end of
278+
* scan or rescan, but that's OK.)
279+
*/
280+
oldCtx=MemoryContextSwitchTo(so->keyCtx);
281281

282282
/* if no scan keys provided, allocate extra EVERYTHING GinScanKey */
283283
so->keys= (GinScanKey)
@@ -412,6 +412,8 @@ ginNewScanKey(IndexScanDesc scan)
412412
RelationGetRelationName(scan->indexRelation))));
413413
}
414414

415+
MemoryContextSwitchTo(oldCtx);
416+
415417
pgstat_count_index_scan(scan->indexRelation);
416418
}
417419

@@ -445,6 +447,7 @@ ginendscan(PG_FUNCTION_ARGS)
445447
ginFreeScanKeys(so);
446448

447449
MemoryContextDelete(so->tempCtx);
450+
MemoryContextDelete(so->keyCtx);
448451

449452
pfree(so);
450453

‎src/include/access/gin_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,8 @@ typedef struct GinScanOpaqueData
888888
uint32totalentries;
889889
uint32allocentries;/* allocated length of entries[] */
890890

891+
MemoryContextkeyCtx;/* used to hold key and entry data */
892+
891893
boolisVoidRes;/* true if query is unsatisfiable */
892894
}GinScanOpaqueData;
893895

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp