aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2011-06-21 14:32:11 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2011-06-21 14:49:50 +0300
commit1eea8e8a06bc718836c34b8f7da9420b38fc4851 (patch)
tree90d68b04494e2aec0330ca731062cdd15cbfe4a4 /src/backend
parent7cb2ff9621a6129cc251f9d06bf23d3f9d426173 (diff)
downloadpostgresql-1eea8e8a06bc718836c34b8f7da9420b38fc4851.tar.gz
postgresql-1eea8e8a06bc718836c34b8f7da9420b38fc4851.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.c15
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;
}