aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/clog.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2008-11-03 19:24:03 +0000
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2008-11-03 19:24:03 +0000
commitd698bf83d16416cf7222c9e825004bdd6b12ad39 (patch)
treeee3d7992cef49449c718c880d26aff2b3d1badba /src/backend/access/transam/clog.c
parent13fc2e4df8fb0cbdf1d004f64c6e1bd059459b5c (diff)
downloadpostgresql-d698bf83d16416cf7222c9e825004bdd6b12ad39.tar.gz
postgresql-d698bf83d16416cf7222c9e825004bdd6b12ad39.zip
Fix TransactionIdSetStatusBit so that it doesn't try to change a transaction
from COMMITTED to SUBCOMMITTED during recovery. This wasn't previously possible, but it is now due to the recent changes on clog commit protocol for subtransactions. Simon Riggs
Diffstat (limited to 'src/backend/access/transam/clog.c')
-rw-r--r--src/backend/access/transam/clog.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index fcff3ea3cfd..3d62417387b 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -26,7 +26,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.48 2008/10/20 19:18:18 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.49 2008/11/03 19:24:03 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -321,13 +321,29 @@ TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, i
int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
char *byteptr;
char byteval;
+ char curval;
byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
+ curval = (*byteptr >> shift) & CLOG_XACT_BITMASK;
- /* Current state should be 0, subcommitted or target state */
- Assert(((*byteptr >> bshift) & CLOG_XACT_BITMASK) == 0 ||
- ((*byteptr >> bshift) & CLOG_XACT_BITMASK) == TRANSACTION_STATUS_SUB_COMMITTED ||
- ((*byteptr >> bshift) & CLOG_XACT_BITMASK) == status);
+ /*
+ * When replaying transactions during recovery we still need to perform
+ * the two phases of subcommit and then commit. However, some transactions
+ * are already correctly marked, so we just treat those as a no-op which
+ * allows us to keep the following Assert as restrictive as possible.
+ */
+ if (InRecovery && status == TRANSACTION_STATUS_SUB_COMMITTED &&
+ curval == TRANSACTION_STATUS_COMMITTED)
+ return;
+
+ /*
+ * Current state change should be from 0 or subcommitted to target state
+ * or we should already be there when replaying changes during recovery.
+ */
+ Assert(curval == 0 ||
+ (curval == TRANSACTION_STATUS_SUB_COMMITTED &&
+ status != TRANSACTION_STATUS_IN_PROGRESS) ||
+ curval == status);
/* note this assumes exclusive access to the clog page */
byteval = *byteptr;