]> granicus.if.org Git - postgresql/commitdiff
Perform transaction cleanup operations in a less ad-hoc, more
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 Oct 2002 22:44:36 +0000 (22:44 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 Oct 2002 22:44:36 +0000 (22:44 +0000)
principled order; in particular ensure that all shared resources
are released before we release transaction locks.  The code used
to release locks before buffer pins, which might explain an ancient
note I have about a bufmgr assertion failure I'd seen once several
years ago, and been unable to reproduce since.  (Theory: someone
trying to drop a relation might be able to reach FlushRelationBuffers
before the last user of the relation had gotten around to dropping
his buffer pins.)

src/backend/access/transam/xact.c

index 4687578feddde4427f6e466458b6a0f32fb10ade..a4d13c5beda98eae3a0541a208852799a4acdddf 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.134 2002/10/21 22:06:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.135 2002/10/22 22:44:36 tgl Exp $
  *
  * NOTES
  *             Transaction aborts can now occur two ways:
@@ -1005,9 +1005,20 @@ CommitTransaction(void)
         * This is all post-commit cleanup.  Note that if an error is raised
         * here, it's too late to abort the transaction.  This should be just
         * noncritical resource releasing.
+        *
+        * The ordering of operations is not entirely random.  The idea is:
+        * release resources visible to other backends (eg, files, buffer pins);
+        * then release locks; then release backend-local resources.  We want
+        * to release locks at the point where any backend waiting for us will
+        * see our transaction as being fully cleaned up.
         */
 
        smgrDoPendingDeletes(true);
+       AtCommit_Cache();
+       AtEOXact_Buffers(true);
+       /* smgrcommit already done */
+
+       AtCommit_Locks();
 
        AtEOXact_GUC(true);
        AtEOXact_SPI();
@@ -1016,15 +1027,10 @@ CommitTransaction(void)
        AtEOXact_nbtree();
        AtEOXact_rtree();
        AtEOXact_Namespace(true);
-       AtCommit_Cache();
-       AtCommit_Locks();
        AtEOXact_CatCache(true);
-       AtCommit_Memory();
-       AtEOXact_Buffers(true);
        AtEOXact_Files();
-
-       /* Count transaction commit in statistics collector */
        pgstat_count_xact_commit();
+       AtCommit_Memory();
 
        /*
         * done with commit processing, set current transaction state back to
@@ -1078,6 +1084,9 @@ AbortTransaction(void)
         */
        s->state = TRANS_ABORT;
 
+       /* Make sure we are in a valid memory context */
+       AtAbort_Memory();
+
        /*
         * Reset user id which might have been changed transiently
         */
@@ -1109,7 +1118,17 @@ AbortTransaction(void)
                LWLockRelease(SInvalLock);
        }
 
+       /*
+        * Post-abort cleanup.  See notes in CommitTransaction() concerning
+        * ordering.
+        */
+
        smgrDoPendingDeletes(false);
+       AtAbort_Cache();
+       AtEOXact_Buffers(false);
+       smgrabort();
+
+       AtAbort_Locks();
 
        AtEOXact_GUC(false);
        AtEOXact_SPI();
@@ -1118,15 +1137,8 @@ AbortTransaction(void)
        AtEOXact_nbtree();
        AtEOXact_rtree();
        AtEOXact_Namespace(false);
-       AtAbort_Cache();
        AtEOXact_CatCache(false);
-       AtAbort_Memory();
-       AtEOXact_Buffers(false);
-       smgrabort();
        AtEOXact_Files();
-       AtAbort_Locks();
-
-       /* Count transaction abort in statistics collector */
        pgstat_count_xact_rollback();
 
        /*