]> granicus.if.org Git - postgresql/commitdiff
Repair incorrect order of operations in GetNewTransactionId(). We must
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Jan 2004 19:16:40 +0000 (19:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Jan 2004 19:16:40 +0000 (19:16 +0000)
complete ExtendCLOG() before advancing nextXid, so that if that routine
fails, the next incoming transaction will try it again.  Per trouble
report from Christopher Kings-Lynne.

src/backend/access/transam/varsup.c

index 6453bad761c8078140c06dd2e3f958f367a60ae5..9a40f7eabc3215fb621e91572b402b81d0ab2b2e 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2000, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.51 2002/09/04 20:31:13 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.51.2.1 2004/01/26 19:16:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,10 +45,8 @@ GetNewTransactionId(void)
 
        xid = ShmemVariableCache->nextXid;
 
-       TransactionIdAdvance(ShmemVariableCache->nextXid);
-
        /*
-        * If we have just allocated the first XID of a new page of the commit
+        * If we are allocating the first XID of a new page of the commit
         * log, zero out that commit-log page before returning. We must do
         * this while holding XidGenLock, else another xact could acquire and
         * commit a later XID before we zero the page.  Fortunately, a page of
@@ -57,6 +55,14 @@ GetNewTransactionId(void)
         */
        ExtendCLOG(xid);
 
+       /*
+        * Now advance the nextXid counter.  This must not happen until after
+        * we have successfully completed ExtendCLOG() --- if that routine fails,
+        * we want the next incoming transaction to try it again.  We cannot
+        * assign more XIDs until there is CLOG space for them.
+        */
+       TransactionIdAdvance(ShmemVariableCache->nextXid);
+
        /*
         * Must set MyProc->xid before releasing XidGenLock.  This ensures
         * that when GetSnapshotData calls ReadNewTransactionId, all active
@@ -74,7 +80,7 @@ GetNewTransactionId(void)
         *
         * A solution to the atomic-store problem would be to give each PGPROC
         * its own spinlock used only for fetching/storing that PGPROC's xid.
-        * (SInvalLock would then mean primarily that PROCs couldn't be added/
+        * (SInvalLock would then mean primarily that PGPROCs couldn't be added/
         * removed while holding the lock.)
         */
        if (MyProc != (PGPROC *) NULL)