Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c8df483

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 4b02e93 commit c8df483

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
@@ -440,8 +440,12 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
440440

441441
END_CRIT_SECTION();
442442

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

447451
/*
@@ -727,7 +731,8 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka,
727731
*/
728732
void
729733
ginInsertCleanup(GinState *ginstate, bool full_clean,
730-
bool fill_fsm, IndexBulkDeleteResult *stats)
734+
bool fill_fsm, bool forceCleanup,
735+
IndexBulkDeleteResult *stats)
731736
{
732737
Relation index = ginstate->index;
733738
Buffer metabuffer,
@@ -744,7 +749,6 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
744749
bool cleanupFinish = false;
745750
bool fsm_vac = false;
746751
Size workMemory;
747-
bool inVacuum = (stats == NULL);
748752

749753
/*
750754
* We would like to prevent concurrent cleanup process. For that we will
@@ -753,7 +757,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
753757
* insertion into pending list
754758
*/
755759

756-
if (inVacuum)
760+
if (forceCleanup)
757761
{
758762
/*
759763
* We are called from [auto]vacuum/analyze or gin_clean_pending_list()
@@ -1016,7 +1020,7 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
10161020

10171021
memset(&stats, 0, sizeof(stats));
10181022
initGinState(&ginstate, indexRel);
1019-
ginInsertCleanup(&ginstate, true, true, &stats);
1023+
ginInsertCleanup(&ginstate, true, true, true, &stats);
10201024

10211025
index_close(indexRel, AccessShareLock);
10221026

src/backend/access/gin/ginvacuum.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
570570
* and cleanup any pending inserts
571571
*/
572572
ginInsertCleanup(&gvs.ginstate, !IsAutoVacuumWorkerProcess(),
573-
false, stats);
573+
false, true, stats);
574574
}
575575

576576
/* we'll re-count the tuples each time */
@@ -683,7 +683,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
683683
if (IsAutoVacuumWorkerProcess())
684684
{
685685
initGinState(&ginstate, index);
686-
ginInsertCleanup(&ginstate, false, true, stats);
686+
ginInsertCleanup(&ginstate, false, true, true, stats);
687687
}
688688
return stats;
689689
}
@@ -697,7 +697,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
697697
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
698698
initGinState(&ginstate, index);
699699
ginInsertCleanup(&ginstate, !IsAutoVacuumWorkerProcess(),
700-
false, stats);
700+
false, true, stats);
701701
}
702702

703703
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
@@ -439,7 +439,7 @@ extern void ginHeapTupleFastCollect(GinState *ginstate,
439439
OffsetNumber attnum, Datum value, bool isNull,
440440
ItemPointer ht_ctid);
441441
extern void ginInsertCleanup(GinState *ginstate, bool full_clean,
442-
bool fill_fsm, IndexBulkDeleteResult *stats);
442+
bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats);
443443

444444
/* ginpostinglist.c */
445445

0 commit comments

Comments
 (0)