diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2011-06-21 14:32:11 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2011-06-21 15:02:32 +0300 |
commit | 390c52131b7a42d7b5528d0435d7f6279bdf0ed0 (patch) | |
tree | eba33c3895ba9445e44a69f43ccbef2dba56aa3f /src/backend | |
parent | 0d905db20b3201bec3ea69951014b473f92223c7 (diff) | |
download | postgresql-390c52131b7a42d7b5528d0435d7f6279bdf0ed0.tar.gz postgresql-390c52131b7a42d7b5528d0435d7f6279bdf0ed0.zip |
Fix bug in PreCommit_CheckForSerializationFailure. A transaction that has
already been marked as PREPARED cannot be killed. Kill the current
transaction instead.
One of the prepared_xacts regression tests actually hits this bug. I
removed the anomaly from the duplicate-gids test so that it fails in the
intended way, and added a new test to check serialization failures with
a prepared transaction.
Dan Ports
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/storage/lmgr/predicate.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 8cbca78fb76..2293c75a9bf 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -4542,6 +4542,21 @@ PreCommit_CheckForSerializationFailure(void) && !SxactIsReadOnly(farConflict->sxactOut) && !SxactIsDoomed(farConflict->sxactOut))) { + /* + * Normally, we kill the pivot transaction to make sure we + * make progress if the failing transaction is retried. + * However, we can't kill it if it's already prepared, so + * in that case we commit suicide instead. + */ + if (SxactIsPrepared(nearConflict->sxactOut)) + { + LWLockRelease(SerializableXactHashLock); + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to read/write dependencies among transactions"), + errdetail("Cancelled on commit attempt with conflict in from prepared pivot."), + errhint("The transaction might succeed if retried."))); + } nearConflict->sxactOut->flags |= SXACT_FLAG_DOOMED; break; } |