postgres.git / summary / log / commit / refs

commit    22f519c92a45eb017bf2e65f36506a75309f8094
Author:   Teodor Sigaev <teodor@sigaev.ru>
Date:     Thu Sep 17 11:22:37 2015 +0000
First released in: 9.6.0

    Fix bug introduced by microvacuum for GiST
    
    Commit 013ebc0a7b7ea9c1b1ab7a3d4dd75ea121ea8ba7 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


src/backend/access/gist/gist.c | 5 +++++ src/backend/access/gist/gistvacuum.c | 11 ++++------- src/backend/access/gist/gistxlog.c | 4 +--- src/include/access/xlog_internal.h | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 4edc5a75f28..53bccf6d185 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -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); diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 2337dbd7f9d..a0b0eebed3d 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -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)) diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c index fbdbb3c51f2..c63cc8190c4 100644 --- a/src/backend/access/gist/gistxlog.c +++ b/src/backend/access/gist/gistxlog.c @@ -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); } diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 5ebaa5f69c6..590bf1729ae 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -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 { [parent: 7aea8e4f2daa]