8000 Fix broken cleanup interlock for GIN pending list. · koderP/postgres@19648ce · GitHub
[go: up one dir, main page]

Skip to content

Commit 19648ce

Browse files
committed
Fix broken cleanup interlock for GIN pending list.
The pending list must (for correctness) always be cleaned up by vacuum, and should (for the avoidance of surprising behavior) always be cleaned up by an explicit call to gin_clean_pending_list, but cleanup is optional when inserting. The old logic got this backward: cleanup was forced if (stats == NULL), but that's going to be *false* when vacuuming and *true* for inserts. Masahiko Sawada, reviewed by me. Discussion: http://postgr.es/m/CAD21AoBLUSyiYKnTYtSAbC+F=XDjiaBrOUEGK+zUXdQ8owfPKw@mail.gmail.com
1 parent 4a15f87 commit 19648ce

File tree

3 files changed

+13
-9
lines changed

3 files changed

+13
-9
lines changed

src/backend/access/gin/ginfast.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,12 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
438438

439439
END_CRIT_SECTION();
440440

441+
/*
442+
* Since it could contend with concurrent cleanup process we cleanup
443+
* pending list not forcibly.
444+
*/
441445
if (needCleanup)
442-
ginInsertCleanup(ginstate, false, true, NULL);
446+
ginInsertCleanup(ginstate, false, true, false, NULL);
443447
}
444448

445449
/*
@@ -725,7 +729,8 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka,
725729
*/
726730
void
727731
ginInsertCleanup(GinState *ginstate, bool full_clean,
728-
bool fill_fsm, IndexBulkDeleteResult *stats)
732+
bool fill_fsm, bool forceCleanup,
733+
IndexBulkDeleteResult *stats)
729734
{
730735
Relation index = ginstate->index;
731736
Buffer metabuffer,
@@ -742,7 +747,6 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
742747
bool cleanupFinish = false;
743748
bool fsm_vac = false;
744749
Size workMemory;
745-
bool inVacuum = (stats == NULL);
746750

747751
/*
748752
* We would like to prevent concurrent cleanup process. For that we will
@@ -751,7 +755,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
751755
* insertion into pending list
752756
*/
753757

754-
if (inVacuum)
758+
if (forceCleanup)
755759
{
756760
/*
757761
* We are called from [auto]vacuum/analyze or gin_clean_pending_list()
@@ -1014,7 +1018,7 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
10141018

10151019
memset(&stats, 0, sizeof(stats));
10161020
initGinState(&ginstate, indexRel);
1017-
ginInsertCleanup(&ginstate, true, true, &stats);
1021+
ginInsertCleanup(&ginstate, true, true, true, &stats);
10181022

10191023
index_close(indexRel, AccessShareLock);
10201024

src/backend/access/gin/ginvacuum.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
543543
* and cleanup any pending inserts
544544
*/
545545
ginInsertCleanup(&gvs.ginstate, !IsAutoVacuumWorkerProcess(),
546-
false, stats);
546+
false, true, stats);
547547
}
548548

549549
/* we'll re-count the tuples each time */
@@ -656,7 +656,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
656656
if (IsAutoVacuumWorkerProcess())
657657
{
658658
initGinState(&ginstate, index);
659-
ginInsertCleanup(&ginstate, false, true, stats);
659+
ginInsertCleanup(&ginstate, false, true, true, stats);
660660
}
661661
return stats;
662662
}
@@ -670,7 +670,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
670670
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
671671
initGinState(&ginstate, index);
672672
ginInsertCleanup(&ginstate, !IsAutoVacuumWorkerProcess(),
673-
false, stats);
673+
false, true, stats);
674674
}
675675

676676
memset(&idxStat, 0, sizeof(idxStat));

src/include/access/gin_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ extern void ginHeapTupleFastCollect(GinState *ginstate,
948948
OffsetNumber attnum, Datum value, bool isNull,
949949
ItemPointer ht_ctid);
950950
extern void ginInsertCleanup(GinState *ginstate, bool full_clean,
951-
bool fill_fsm, IndexBulkDeleteResult *stats);
951+
bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats);
952952

953953
/* ginpostinglist.c */
954954

0 commit comments

Comments
 (0)
0