]> granicus.if.org Git - postgresql/commitdiff
Fix bug introduced by microvacuum for GiST
authorTeodor Sigaev <teodor@sigaev.ru>
Thu, 17 Sep 2015 11:22:37 +0000 (14:22 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Thu, 17 Sep 2015 11:22:37 +0000 (14:22 +0300)
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
src/backend/access/gist/gistvacuum.c
src/backend/access/gist/gistxlog.c
src/include/access/xlog_internal.h

index 4edc5a75f2836c14f79d78155162646bfb5d5cd3..53bccf6d185b37c44a2fdd00d0b946e1817d1e95 100644 (file)
@@ -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);
index 2337dbd7f9d71e6fd51bdf94643dae67c2e1ea8d..a0b0eebed3dbf704cc0dcfe23c42542a96ada245 100644 (file)
@@ -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))
index fbdbb3c51f2e7fc7e40c918bffe063537836233e..c63cc8190c4d3722eb9451076d546b1886512c21 100644 (file)
@@ -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);
                }
index 5ebaa5f69c6aa42fdd78e923f21be8eaef69d5d1..590bf1729ae358fe1b42c416112e7778d490124c 100644 (file)
@@ -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
 {