diff options
| author | Tom Lane | 2004-07-28 14:23:31 +0000 |
|---|---|---|
| committer | Tom Lane | 2004-07-28 14:23:31 +0000 |
| commit | 1bf3d615047eb214b1ddde31bd268dabf96cc3fa (patch) | |
| tree | 0fdb8cc0a4203c338b6f73130c9ef74b64d4a74e /src/backend/utils | |
| parent | cc813fc2b8d9293bbd4d0e0d6a6f3b9cf02fe32f (diff) | |
Fix subtransaction behavior for large objects, temp namespace, files,
password/group files. Also allow read-only subtransactions of a read-write
parent, but not vice versa. These are the reasonably noncontroversial
parts of Alvaro's recent mop-up patch, plus further work on large objects
to minimize use of the TopTransactionResourceOwner.
Diffstat (limited to 'src/backend/utils')
| -rw-r--r-- | src/backend/utils/cache/inval.c | 6 | ||||
| -rw-r--r-- | src/backend/utils/misc/guc.c | 15 | ||||
| -rw-r--r-- | src/backend/utils/time/tqual.c | 65 |
3 files changed, 67 insertions, 19 deletions
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index e54a74fae4b..946bd0c9eb7 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -80,7 +80,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.63 2004/07/01 00:51:17 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.64 2004/07/28 14:23:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -678,7 +678,7 @@ AtEOXact_Inval(bool isCommit) } /* - * AtSubEOXact_Inval + * AtEOSubXact_Inval * Process queued-up invalidation messages at end of subtransaction. * * If isCommit, process CurrentCmdInvalidMsgs if any (there probably aren't), @@ -695,7 +695,7 @@ AtEOXact_Inval(bool isCommit) * (if aborting). */ void -AtSubEOXact_Inval(bool isCommit) +AtEOSubXact_Inval(bool isCommit) { TransInvalidationInfo *myInfo = transInvalInfo; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b9865462a4e..22df3effc32 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <[email protected]>. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.224 2004/07/24 19:51:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.225 2004/07/28 14:23:29 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -5436,10 +5436,15 @@ assign_log_stats(bool newval, bool doit, GucSource source) static bool assign_transaction_read_only(bool newval, bool doit, GucSource source) { - if (doit && source >= PGC_S_INTERACTIVE && IsSubTransaction()) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot set transaction read only mode inside a subtransaction"))); + /* Can't go to r/w mode inside a r/o transaction */ + if (newval == false && XactReadOnly && IsSubTransaction()) + { + if (source >= PGC_S_INTERACTIVE) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot set transaction read-write mode inside a read-only transaction"))); + return false; + } return true; } diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 446ee4b72c5..d1a7179484e 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -16,7 +16,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.73 2004/07/01 00:51:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.74 2004/07/28 14:23:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -118,7 +118,10 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) /* deleting subtransaction aborted */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) + { + tuple->t_infomask |= HEAP_XMAX_INVALID; return true; + } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); @@ -268,7 +271,10 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) /* deleting subtransaction aborted */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) + { + tuple->t_infomask |= HEAP_XMAX_INVALID; return true; + } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); @@ -452,7 +458,10 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid) /* deleting subtransaction aborted */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) + { + tuple->t_infomask |= HEAP_XMAX_INVALID; return HeapTupleMayBeUpdated; + } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); @@ -590,7 +599,10 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) /* deleting subtransaction aborted */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) + { + tuple->t_infomask |= HEAP_XMAX_INVALID; return true; + } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); @@ -732,7 +744,10 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) /* deleting subtransaction aborted */ /* FIXME -- is this correct w.r.t. the cmax of the tuple? */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) + { + tuple->t_infomask |= HEAP_XMAX_INVALID; return true; + } Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple))); @@ -757,21 +772,36 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) /* * By here, the inserting transaction has committed - have to check * when... + * + * Note that the provided snapshot contains only top-level XIDs, so + * we have to convert a subxact XID to its parent for comparison. + * However, we can make first-pass range checks with the given XID, + * because a subxact with XID < xmin has surely also got a parent with + * XID < xmin, while one with XID >= xmax must belong to a parent that + * was not yet committed at the time of this snapshot. */ if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple), snapshot->xmin)) { - uint32 i; + TransactionId parentXid; if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple), snapshot->xmax)) return false; - for (i = 0; i < snapshot->xcnt; i++) + parentXid = SubTransGetTopmostTransaction(HeapTupleHeaderGetXmin(tuple)); + + if (TransactionIdFollowsOrEquals(parentXid, snapshot->xmin)) { - if (SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmin(tuple), - snapshot->xip[i])) - return false; + uint32 i; + + /* no point in checking parentXid against xmax here */ + + for (i = 0; i < snapshot->xcnt; i++) + { + if (TransactionIdEquals(parentXid, snapshot->xip[i])) + return false; + } } } @@ -804,18 +834,31 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) /* * OK, the deleting transaction committed too ... but when? + * + * See notes for the similar tests on tuple xmin, above. */ - if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple), snapshot->xmin)) + if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple), + snapshot->xmin)) { - uint32 i; + TransactionId parentXid; if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple), snapshot->xmax)) return true; - for (i = 0; i < snapshot->xcnt; i++) + + parentXid = SubTransGetTopmostTransaction(HeapTupleHeaderGetXmax(tuple)); + + if (TransactionIdFollowsOrEquals(parentXid, snapshot->xmin)) { - if (SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmax(tuple), snapshot->xip[i])) - return true; + uint32 i; + + /* no point in checking parentXid against xmax here */ + + for (i = 0; i < snapshot->xcnt; i++) + { + if (TransactionIdEquals(parentXid, snapshot->xip[i])) + return true; + } } } |
