Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d6a7271

Browse files
committed
Correctly detect SSI conflicts of prepared transactions after crash.
A prepared transaction can get new conflicts in and out after preparing, so we cannot rely on the in- and out-flags stored in the statefile at prepare- time. As a quick fix, make the conservative assumption that after a restart, all prepared transactions are considered to have both in- and out-conflicts. That can lead to unnecessary rollbacks after a crash, but that shouldn't be a big problem in practice; you don't want prepared transactions to hang around for a long time anyway. Dan Ports
1 parent 8cae581 commit d6a7271

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

src/backend/storage/lmgr/predicate.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4730,14 +4730,11 @@ AtPrepare_PredicateLocks(void)
47304730
xactRecord->flags = MySerializableXact->flags;
47314731

47324732
/*
4733-
* Tweak the flags. Since we're not going to output the inConflicts and
4734-
* outConflicts lists, if they're non-empty we'll represent that by
4735-
* setting the appropriate summary conflict flags.
4733+
* Note that we don't include the list of conflicts in our out in
4734+
* the statefile, because new conflicts can be added even after the
4735+
* transaction prepares. We'll just make a conservative assumption
4736+
* during recovery instead.
47364737
*/
4737-
if (!SHMQueueEmpty(&MySerializableXact->inConflicts))
4738-
xactRecord->flags |= SXACT_FLAG_SUMMARY_CONFLICT_IN;
4739-
if (!SHMQueueEmpty(&MySerializableXact->outConflicts))
4740-
xactRecord->flags |= SXACT_FLAG_SUMMARY_CONFLICT_OUT;
47414738

47424739
RegisterTwoPhaseRecord(TWOPHASE_RM_PREDICATELOCK_ID, 0,
47434740
&record, sizeof(record));
@@ -4872,15 +4869,6 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
48724869

48734870
sxact->SeqNo.lastCommitBeforeSnapshot = RecoverySerCommitSeqNo;
48744871

4875-
4876-
/*
4877-
* We don't need the details of a prepared transaction's conflicts,
4878-
* just whether it had conflicts in or out (which we get from the
4879-
* flags)
4880-
*/
4881-
SHMQueueInit(&(sxact->outConflicts));
4882-
SHMQueueInit(&(sxact->inConflicts));
4883-
48844872
/*
48854873
* Don't need to track this; no transactions running at the time the
48864874
* recovered xact started are still active, except possibly other
@@ -4902,6 +4890,17 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
49024890
(MaxBackends + max_prepared_xacts));
49034891
}
49044892

4893+
/*
4894+
* We don't know whether the transaction had any conflicts or
4895+
* not, so we'll conservatively assume that it had both a
4896+
* conflict in and a conflict out, and represent that with the
4897+
* summary conflict flags.
4898+
*/
4899+
SHMQueueInit(&(sxact->outConflicts));
4900+
SHMQueueInit(&(sxact->inConflicts));
4901+
sxact->flags |= SXACT_FLAG_SUMMARY_CONFLICT_IN;
4902+
sxact->flags |= SXACT_FLAG_SUMMARY_CONFLICT_OUT;
4903+
49054904
/* Register the transaction's xid */
49064905
sxidtag.xid = xid;
49074906
sxid = (SERIALIZABLEXID *) hash_search(SerializableXidHash,

0 commit comments

Comments
 (0)