Allow autoanalyze to add pages deleted from pending list to FSM

Commit e956808328 introduces adding pages
to FSM for ordinary insert, but autoanalyze was able just cleanup
pending list without adding to FSM.

Also fix double call of IndexFreeSpaceMapVacuum() during ginvacuumcleanup()

Report from Fujii Masao
Patch by me
Review by Jeff Janes
This commit is contained in:
Teodor Sigaev 2015-09-23 15:33:51 +03:00
parent 262e56bcae
commit dc943ad952
3 changed files with 18 additions and 12 deletions

View File

@ -434,7 +434,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
END_CRIT_SECTION();
if (needCleanup)
ginInsertCleanup(ginstate, false, NULL);
ginInsertCleanup(ginstate, false, true, NULL);
}
/*
@ -505,7 +505,7 @@ ginHeapTupleFastCollect(GinState *ginstate,
*/
static bool
shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
IndexBulkDeleteResult *stats)
bool fill_fsm, IndexBulkDeleteResult *stats)
{
Page metapage;
GinMetaPageData *metadata;
@ -613,7 +613,7 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
END_CRIT_SECTION();
for (i = 0; i < data.ndeleted; i++)
for (i = 0; fill_fsm && i < data.ndeleted; i++)
RecordFreeIndexPage(index, freespace[i]);
} while (blknoToDelete != newHead);
@ -732,13 +732,19 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka,
* action of removing a page from the pending list really needs exclusive
* lock.
*
* vac_delay indicates that ginInsertCleanup is called from vacuum process,
* so call vacuum_delay_point() periodically.
* vac_delay indicates that ginInsertCleanup should call
* vacuum_delay_point() periodically.
*
* fill_fsm indicates that ginInsertCleanup should add deleted pages
* to FSM otherwise caller is responsible to put deleted pages into
* FSM.
*
* If stats isn't null, we count deleted pending pages into the counts.
*/
void
ginInsertCleanup(GinState *ginstate,
bool vac_delay, IndexBulkDeleteResult *stats)
bool vac_delay, bool fill_fsm,
IndexBulkDeleteResult *stats)
{
Relation index = ginstate->index;
Buffer metabuffer,
@ -899,7 +905,7 @@ ginInsertCleanup(GinState *ginstate,
* remove read pages from pending list, at this point all
* content of read pages is in regular structure
*/
if (shiftList(index, metabuffer, blkno, stats))
if (shiftList(index, metabuffer, blkno, fill_fsm, stats))
{
/* another cleanup process is running concurrently */
LockBuffer(metabuffer, GIN_UNLOCK);
@ -948,7 +954,7 @@ ginInsertCleanup(GinState *ginstate,
* desirable to recycle them immediately to the FreeSpace Map when
* ordinary backends clean the list.
*/
if (fsm_vac && !vac_delay)
if (fsm_vac && fill_fsm)
IndexFreeSpaceMapVacuum(index);

View File

@ -544,7 +544,7 @@ ginbulkdelete(PG_FUNCTION_ARGS)
/* Yes, so initialize stats to zeroes */
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
/* and cleanup any pending inserts */
ginInsertCleanup(&gvs.ginstate, true, stats);
ginInsertCleanup(&gvs.ginstate, true, false, stats);
}
/* we'll re-count the tuples each time */
@ -659,7 +659,7 @@ ginvacuumcleanup(PG_FUNCTION_ARGS)
if (IsAutoVacuumWorkerProcess())
{
initGinState(&ginstate, index);
ginInsertCleanup(&ginstate, true, stats);
ginInsertCleanup(&ginstate, true, true, stats);
}
PG_RETURN_POINTER(stats);
}
@ -672,7 +672,7 @@ ginvacuumcleanup(PG_FUNCTION_ARGS)
{
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
initGinState(&ginstate, index);
ginInsertCleanup(&ginstate, true, stats);
ginInsertCleanup(&ginstate, true, false, stats);
}
memset(&idxStat, 0, sizeof(idxStat));

View File

@ -936,7 +936,7 @@ extern void ginHeapTupleFastCollect(GinState *ginstate,
OffsetNumber attnum, Datum value, bool isNull,
ItemPointer ht_ctid);
extern void ginInsertCleanup(GinState *ginstate,
bool vac_delay, IndexBulkDeleteResult *stats);
bool vac_delay, bool fill_fsm, IndexBulkDeleteResult *stats);
/* ginpostinglist.c */