Commit 22f519c9 authored by Teodor Sigaev's avatar Teodor Sigaev

Fix bug introduced by microvacuum for GiST

Commit 013ebc0a introduces microvacuum for
GiST, deletetion of tuple marked LP_DEAD uses IndexPageMultiDelete while
recovery code uses IndexPageTupleDelete in loop. This causes a difference
in offset numbers of tuples to delete. Patch introduces usage of
IndexPageMultiDelete in GiST except gistplacetopage() where only one tuple is
deleted at once. That also slightly improve performance, because
IndexPageMultiDelete is more effective.

Patch changes WAL format, so bump wal page magic.

Bug report from Jeff Janes
Diagnostic and patch by Anastasia Lubennikova and me
parent 7aea8e4f
......@@ -466,6 +466,11 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
*/
START_CRIT_SECTION();
/*
* While we delete only one tuple at once we could mix calls
* PageIndexTupleDelete() here and PageIndexMultiDelete() in
* gistRedoPageUpdateRecord()
*/
if (OffsetNumberIsValid(oldoffnum))
PageIndexTupleDelete(page, oldoffnum);
gistfillbuffer(page, itup, ntup, InvalidOffsetNumber);
......
......@@ -208,23 +208,20 @@ gistbulkdelete(PG_FUNCTION_ARGS)
idxtuple = (IndexTuple) PageGetItem(page, iid);
if (callback(&(idxtuple->t_tid), callback_state))
{
todelete[ntodelete] = i - ntodelete;
ntodelete++;
stats->tuples_removed += 1;
}
todelete[ntodelete++] = i;
else
stats->num_index_tuples += 1;
}
stats->tuples_removed += ntodelete;
if (ntodelete)
{
START_CRIT_SECTION();
MarkBufferDirty(buffer);
for (i = 0; i < ntodelete; i++)
PageIndexTupleDelete(page, todelete[i]);
PageIndexMultiDelete(page, todelete, ntodelete);
GistMarkTuplesDeleted(page);
if (RelationNeedsWAL(rel))
......
......@@ -83,13 +83,11 @@ gistRedoPageUpdateRecord(XLogReaderState *record)
/* Delete old tuples */
if (xldata->ntodelete > 0)
{
int i;
OffsetNumber *todelete = (OffsetNumber *) data;
data += sizeof(OffsetNumber) * xldata->ntodelete;
for (i = 0; i < xldata->ntodelete; i++)
PageIndexTupleDelete(page, todelete[i]);
PageIndexMultiDelete(page, todelete, xldata->ntodelete);
if (GistPageIsLeaf(page))
GistMarkTuplesDeleted(page);
}
......
......@@ -31,7 +31,7 @@
/*
* Each page of XLOG file has a header like this:
*/
#define XLOG_PAGE_MAGIC 0xD085 /* can be used as WAL version indicator */
#define XLOG_PAGE_MAGIC 0xD086 /* can be used as WAL version indicator */
typedef struct XLogPageHeaderData
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment