]> granicus.if.org Git - postgresql/commitdiff
Initialize tsId and dbId fields in WAL record of COMMIT PREPARED.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 16 May 2014 06:47:50 +0000 (09:47 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 16 May 2014 07:05:57 +0000 (10:05 +0300)
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

index c648af98f830554df27ef659a0f645f84f5982b4..c269cd633c4f2bcd6c5f45741242f598073aecdf 100644 (file)
@@ -2092,9 +2092,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;