mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
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
This commit is contained in:
parent
13fc2e4df8
commit
d698bf83d1
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user