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

Commit 3b2787e

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 6b2cd27 commit 3b2787e

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

451451
END_CRIT_SECTION();
452452

453+
/*
454+
* Since it could contend with concurrent cleanup process we cleanup
455+
* pending list not forcibly.
456+
*/
453457
if (needCleanup)
454-
ginInsertCleanup(ginstate, false, true, NULL);
458+
ginInsertCleanup(ginstate, false, true, false, NULL);
455459
}
456460

457461
/*
@@ -748,7 +752,8 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka,
748752
*/
749753
void
750754
ginInsertCleanup(GinState *ginstate, bool full_clean,
751-
bool fill_fsm, IndexBulkDeleteResult *stats)
755+
bool fill_fsm, bool forceCleanup,
756+
IndexBulkDeleteResult *stats)
752757
{
753758
Relation index = ginstate->index;
754759
Buffer metabuffer,
@@ -765,7 +770,6 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
765770
bool cleanupFinish = false;
766771
bool fsm_vac = false;
767772
Size workMemory;
768-
bool inVacuum = (stats == NULL);
769773

770774
/*
771775
* We would like to prevent concurrent cleanup process. For that we will
@@ -774,7 +778,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
774778
* insertion into pending list
775779
*/
776780

777-
if (inVacuum)
781+
if (forceCleanup)
778782
{
779783
/*
780784
* We are called from [auto]vacuum/analyze or gin_clean_pending_list()
@@ -1036,7 +1040,7 @@ gin_clean_pending_list(PG_FUNCTION_ARGS)
10361040

10371041
memset(&stats, 0, sizeof(stats));
10381042
initGinState(&ginstate, indexRel);
1039-
ginInsertCleanup(&ginstate, true, true, &stats);
1043+
ginInsertCleanup(&ginstate, true, true, true, &stats);
10401044

10411045
index_close(indexRel, AccessShareLock);
10421046

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)