postgres.git / summary / log / commit / refs

commit    be249420414e3d2a613aa1f295656a2a820b7941
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:     Mon Apr 28 13:12:45 2014 +0000

    Fix two bugs in WAL-logging of GIN pending-list pages.
    
    In writeListPage, never take a full-page image of the page, because we
    have all the information required to re-initialize in the WAL record
    anyway. Before this fix, a full-page image was always generated, unless
    full_page_writes=off, because when the page is initialized its LSN is
    always 0. In stable-branches, keep the code to restore the backup blocks
    if they exist, in case that the WAL is generated with an older minor
    version, but in master Assert that there are no full-page images.
    
    In the redo routine, add missing "off++". Otherwise the tuples are added
    to the page in reverse order. That happens to be harmless because we
    always scan and remove all the tuples together, but it was clearly wrong.
    Also, it was masked by the first bug unless full_page_writes=off, because
    the page was always restored from a full-page image.
    
    Backpatch to all supported versions.


src/backend/access/gin/ginfast.c | 3 +-- src/backend/access/gin/ginxlog.c | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index fb6710e7e49..71f6cb3741e 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -119,8 +119,7 @@ writeListPage(Relation index, Buffer buffer, rdata[0].len = sizeof(ginxlogInsertListPage); rdata[0].next = rdata + 1; - rdata[1].buffer = buffer; - rdata[1].buffer_std = true; + rdata[1].buffer = InvalidBuffer; rdata[1].data = workspace; rdata[1].len = size; rdata[1].next = NULL; diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index f66938a1303..2344ec25bcf 100644 --- a/src/backend/access/gin/ginxlog.c +++ b/src/backend/access/gin/ginxlog.c @@ -587,6 +587,11 @@ ginRedoInsertListPage(XLogRecPtr lsn, XLogRecord *record) tupsize; IndexTuple tuples = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogInsertListPage)); + /* + * If we have a full-page image, we're done. (As the code stands, we + * never create full-page images, but we used to. Cope if we're + * reading WAL generated with an older minor version.) + */ if (record->xl_info & XLR_BKP_BLOCK_1) return; @@ -617,6 +622,7 @@ ginRedoInsertListPage(XLogRecPtr lsn, XLogRecord *record) elog(ERROR, "failed to add item to index page"); tuples = (IndexTuple) (((char *) tuples) + tupsize); + off++; } PageSetLSN(page, lsn); [parent: 82fbd88a7b0d]