postgres.git / summary / log / commit / refs

commit    0fc94340753f19da8acca5fc53039adbf2fa3632
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:     Fri May 16 06:47:50 2014 +0000
First released in: 9.4.0, 9.0.18, 9.1.14, 9.2.9, 9.3.5

    Initialize tsId and dbId fields in WAL record of COMMIT PREPARED.
    
    Commit dd428c79 added dbId and tsId to the xl_xact_commit struct but missed
    that prepared transaction commits reuse that struct. Fix that.
    
    Because those fields were left unitialized, replaying a commit prepared WAL
    record in a hot standby node would fail to remove the relcache init file.
    That can lead to "could not open file" errors on the standby. Relcache init
    file only needs to be removed when a system table/index is rewritten in the
    transaction using two phase commit, so that should be rare in practice. In
    HEAD, the incorrect dbId/tsId values are also used for filtering in logical
    replication code, causing the transaction to always be filtered out.
    
    Analysis and fix by Andres Freund. Backpatch to 9.0 where hot standby was
    introduced.


src/backend/access/transam/twophase.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 7e83b8bec4a..c29f86bec3a 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -2035,9 +2035,13 @@ RecordTransactionCommitPrepared(TransactionId xid, /* Emit the XLOG commit record */ xlrec.xid = xid; - xlrec.crec.xact_time = GetCurrentTimestamp(); + xlrec.crec.xinfo = initfileinval ? XACT_COMPLETION_UPDATE_RELCACHE_FILE : 0; - xlrec.crec.nmsgs = 0; + + xlrec.crec.dbId = MyDatabaseId; + xlrec.crec.tsId = MyDatabaseTableSpace; + + xlrec.crec.xact_time = GetCurrentTimestamp(); xlrec.crec.nrels = nrels; xlrec.crec.nsubxacts = nchildren; xlrec.crec.nmsgs = ninvalmsgs; [parent: 9fb8cd25fd98]