]> granicus.if.org Git - postgresql/commitdiff
Fix full-page writes of internal GIN pages.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 3 Dec 2013 20:13:16 +0000 (22:13 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 3 Dec 2013 21:16:01 +0000 (23:16 +0200)
Insertion to a non-leaf GIN page didn't make a full-page image of the page,
which is wrong. The code used to do it correctly, but was changed (commit
853d1c3103fa961ae6219f0281885b345593d101) because the redo-routine didn't
track incomplete splits correctly when the page was restored from a full
page image. Of course, that was not right way to fix it, the redo routine
should've been fixed instead. The redo-routine was surreptitiously fixed
in 2010 (commit 4016bdef8aded77b4903c457050622a5a1815c16), so all we need
to do now is revert the code that creates the record to its original form.

This doesn't change the format of the WAL record.

Backpatch to all supported versions.

src/backend/access/gin/gindatapage.c
src/backend/access/gin/ginentrypage.c

index 5221f5e92f00564e8f1ad189351f037b72e797b6..36d13171212accff2e6e30ce2d3e7e9b226317eb 100644 (file)
@@ -382,12 +382,14 @@ dataPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off,
                        data.nitem = 1;
                }
 
-               rdata[0].buffer = InvalidBuffer;
+               rdata[0].buffer = buf;
+               rdata[0].buffer_std = false;
                rdata[0].data = (char *) &data;
                rdata[0].len = offsetof(ginxlogInsertDataLeaf, items);
                rdata[0].next = &rdata[1];
 
-               rdata[1].buffer = InvalidBuffer;
+               rdata[1].buffer = buf;
+               rdata[1].buffer_std = false;
                rdata[1].data = (char *) &items->items[savedPos];
                rdata[1].len = sizeof(ItemPointerData) * data.nitem;
                rdata[1].next = NULL;
@@ -398,7 +400,8 @@ dataPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off,
 
                GinDataPageAddPostingItem(page, pitem, off);
 
-               rdata[0].buffer = InvalidBuffer;
+               rdata[0].buffer = buf;
+               rdata[0].buffer_std = false;
                rdata[0].data = (char *) pitem;
                rdata[0].len = sizeof(PostingItem);
                rdata[0].next = NULL;
index 89cde4aec0107664e46c0c4b917d1cbe727b8ad5..e754d05ec97a9485331737d0e3ae3b51ad78c9b7 100644 (file)
@@ -523,13 +523,15 @@ entryPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off,
 
        data.isDelete = insertData->isDelete;
 
-       rdata[cnt].buffer = InvalidBuffer;
+       rdata[cnt].buffer = buf;
+       rdata[cnt].buffer_std = false;
        rdata[cnt].data = (char *) &data;
        rdata[cnt].len = offsetof(ginxlogInsertEntry, tuple);
        rdata[cnt].next = &rdata[cnt + 1];
        cnt++;
 
-       rdata[cnt].buffer = InvalidBuffer;
+       rdata[cnt].buffer = buf;
+       rdata[cnt].buffer_std = false;
        rdata[cnt].data = (char *) insertData->entry;
        rdata[cnt].len = IndexTupleSize(insertData->entry);
        rdata[cnt].next = NULL;