Skip to content

Commit eec6099

Browse files
committed
Actually deleting pages
1 parent d596ecd commit eec6099

File tree

1 file changed

+112
-7
lines changed

1 file changed

+112
-7
lines changed

src/backend/access/gist/gistvacuum.c

Lines changed: 112 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,6 @@ typedef struct GistBDItem
108108
struct GistBDItem *next;
109109
} GistBDItem;
110110

111-
typedef struct GistBDSItem
112-
{
113-
BlockNumber blkno;
114-
bool isParent;
115-
struct GistBDSItem *next;
116-
} GistBDSItem;
117-
118111
typedef enum
119112
{
120113
NOT_NEED_TO_PROCESS, /* without action */
@@ -164,6 +157,9 @@ gistbulkdelete(IndexVacuumInfo * info, IndexBulkDeleteResult * stats, IndexBulkD
164157
Relation rel = info->index;
165158
GistBDItem *stack,
166159
*ptr;
160+
BlockNumber recentParent = InvalidBlockNumber;
161+
List *rescanList = NULL;
162+
ListCell *cell;
167163

168164
/* first time through? */
169165
if (stats == NULL)
@@ -256,9 +252,16 @@ gistbulkdelete(IndexVacuumInfo * info, IndexBulkDeleteResult * stats, IndexBulkD
256252
END_CRIT_SECTION();
257253
}
258254

255+
if (ntodelete == maxoff && recentParent!=InvalidBlockNumber &&
256+
(rescanList == NULL || (BlockNumber)llast_int(rescanList) != recentParent))
257+
{
258+
/* This page is a candidate to be deleted. Remember it's parent to rescan it later with xlock */
259+
rescanList = lappend_int(rescanList, recentParent);
260+
}
259261
}
260262
else
261263
{
264+
recentParent = stack->blkno;
262265
/* check for split proceeded after look at parent */
263266
pushStackIfSplited(page, stack);
264267

@@ -293,5 +296,107 @@ gistbulkdelete(IndexVacuumInfo * info, IndexBulkDeleteResult * stats, IndexBulkD
293296
vacuum_delay_point();
294297
}
295298

299+
300+
elog(NOTICE,"Rescan list length %d", length(rescanList));
301+
/* rescan inner pages that had empty child pages */
302+
foreach(cell,rescanList)
303+
{
304+
Buffer buffer;
305+
Page page;
306+
OffsetNumber i,
307+
maxoff;
308+
IndexTuple idxtuple;
309+
ItemId iid;
310+
OffsetNumber todelete[MaxOffsetNumber];
311+
Buffer buftodelete[MaxOffsetNumber];
312+
int ntodelete = 0;
313+
314+
elog(NOTICE,"Deleting for inner %d",(BlockNumber)lfirst_int(cell));
315+
buffer = ReadBufferExtended(rel, MAIN_FORKNUM, (BlockNumber)lfirst_int(cell),
316+
RBM_NORMAL, info->strategy);
317+
LockBuffer(buffer, GIST_EXCLUSIVE);
318+
gistcheckpage(rel, buffer);
319+
page = (Page) BufferGetPage(buffer);
320+
321+
Assert(!GistPageIsLeaf(page));
322+
323+
maxoff = PageGetMaxOffsetNumber(page);
324+
325+
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
326+
{
327+
Buffer leafBuffer;
328+
Page leafPage;
329+
330+
iid = PageGetItemId(page, i);
331+
idxtuple = (IndexTuple) PageGetItem(page, iid);
332+
333+
leafBuffer = ReadBufferExtended(rel, MAIN_FORKNUM, ItemPointerGetBlockNumber(&(idxtuple->t_tid)),
334+
RBM_NORMAL, info->strategy);
335+
LockBuffer(leafBuffer, GIST_EXCLUSIVE);
336+
gistcheckpage(rel, leafBuffer);
337+
leafPage = (Page) BufferGetPage(leafBuffer);
338+
339+
if (PageGetMaxOffsetNumber(leafPage) == InvalidOffsetNumber
340+
&& !(GistFollowRight(leafPage) || GistPageGetNSN(page) < GistPageGetNSN(leafPage)))
341+
{
342+
buftodelete[ntodelete] = leafBuffer;
343+
todelete[ntodelete++] = i;
344+
}
345+
else
346+
UnlockReleaseBuffer(leafBuffer);
347+
}
348+
349+
if (ntodelete)
350+
{
351+
START_CRIT_SECTION();
352+
353+
MarkBufferDirty(buffer);
354+
355+
PageIndexMultiDelete(page, todelete, ntodelete);
356+
GistMarkTuplesDeleted(page);
357+
358+
if (RelationNeedsWAL(rel))
359+
{
360+
XLogRecPtr recptr;
361+
362+
recptr = gistXLogUpdate(buffer,
363+
todelete, ntodelete,
364+
NULL, 0, InvalidBuffer);
365+
PageSetLSN(page, recptr);
366+
}
367+
else
368+
PageSetLSN(page, gistGetFakeLSN(rel));
369+
370+
END_CRIT_SECTION();
371+
372+
for (i = 0; i < ntodelete; i++)
373+
{
374+
Page leafPage = (Page)BufferGetPage(buftodelete[i]);
375+
PageHeader header = (PageHeader)leafPage;
376+
377+
header->pd_prune_xid = GetCurrentTransactionId();
378+
379+
GistPageSetDeleted(leafPage);
380+
stats->pages_deleted++;
381+
382+
if (RelationNeedsWAL(rel))
383+
{
384+
XLogRecPtr recptr;
385+
386+
recptr = gistXLogSetDeleted(rel->rd_node, buftodelete[i], header->pd_prune_xid);
387+
PageSetLSN(leafPage, recptr);
388+
}
389+
else
390+
PageSetLSN(leafPage, gistGetFakeLSN(rel));
391+
392+
UnlockReleaseBuffer(buftodelete[i]);
393+
}
394+
}
395+
396+
UnlockReleaseBuffer(buffer);
397+
}
398+
399+
list_free(rescanList);
400+
296401
return stats;
297402
}

0 commit comments

Comments
 (0)