4242 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
4343 * Portions Copyright (c) 1994, Regents of the University of California
4444 *
45- * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.10 2005/10/2817:27:29 tgl Exp $
45+ * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.11 2005/10/2819:00:19 tgl Exp $
4646 *
4747 *-------------------------------------------------------------------------
4848 */
@@ -630,22 +630,13 @@ CreateMultiXactId(int nxids, TransactionId *xids)
630630return multi ;
631631}
632632
633- /*
634- * Critical section from here until we've written the data; we don't
635- * want to error out with a partly written MultiXact structure.
636- * (In particular, failing to write our start offset after advancing
637- * nextMXact would effectively corrupt the previous MultiXact.)
638- */
639- START_CRIT_SECTION ();
640-
641633/*
642634 * Assign the MXID and offsets range to use, and make sure there is
643- * space in the OFFSETs and MEMBERs files.
635+ * space in the OFFSETs and MEMBERs files. NB: this routine does
636+ * START_CRIT_SECTION().
644637 */
645638multi = GetNewMultiXactId (nxids ,& offset );
646639
647- debug_elog4 (DEBUG2 ,"Create: assigned id %u offset %u" ,multi ,offset );
648-
649640/*
650641 * Make an XLOG entry describing the new MXID.
651642 *
@@ -768,6 +759,9 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
768759 * files. Unfortunately, we have to do that while holding MultiXactGenLock
769760 * to avoid race conditions --- the XLOG record for zeroing a page must appear
770761 * before any backend can possibly try to store data in that page!
762+ *
763+ * We start a critical section before advancing the shared counters. The
764+ * caller must end the critical section after writing SLRU data.
771765 */
772766static MultiXactId
773767GetNewMultiXactId (int nxids ,MultiXactOffset * offset )
@@ -794,18 +788,7 @@ GetNewMultiXactId(int nxids, MultiXactOffset *offset)
794788ExtendMultiXactOffset (result );
795789
796790/*
797- * Advance counter. As in GetNewTransactionId(), this must not happen
798- * until after ExtendMultiXactOffset has succeeded!
799- *
800- * We don't care about MultiXactId wraparound here; it will be handled by
801- * the next iteration.But note that nextMXact may be InvalidMultiXactId
802- * after this routine exits, so anyone else looking at the variable must
803- * be prepared to deal with that.
804- */
805- (MultiXactState -> nextMXact )++ ;
806-
807- /*
808- * Reserve the members space. Same considerations as above. Also, be
791+ * Reserve the members space, similarly to above. Also, be
809792 * careful not to return zero as the starting offset for any multixact.
810793 * See GetMultiXactIdMembers() for motivation.
811794 */
@@ -820,6 +803,27 @@ GetNewMultiXactId(int nxids, MultiXactOffset *offset)
820803
821804ExtendMultiXactMember (nextOffset ,nxids );
822805
806+ /*
807+ * Critical section from here until caller has written the data into
808+ * the just-reserved SLRU space; we don't want to error out with a partly
809+ * written MultiXact structure. (In particular, failing to write our
810+ * start offset after advancing nextMXact would effectively corrupt the
811+ * previous MultiXact.)
812+ */
813+ START_CRIT_SECTION ();
814+
815+ /*
816+ * Advance counters. As in GetNewTransactionId(), this must not happen
817+ * until after file extension has succeeded!
818+ *
819+ * We don't care about MultiXactId wraparound here; it will be handled by
820+ * the next iteration.But note that nextMXact may be InvalidMultiXactId
821+ * after this routine exits, so anyone else looking at the variable must
822+ * be prepared to deal with that. Similarly, nextOffset may be zero,
823+ * but we won't use that as the actual start offset of the next multixact.
824+ */
825+ (MultiXactState -> nextMXact )++ ;
826+
823827MultiXactState -> nextOffset += nxids ;
824828
825829LWLockRelease (MultiXactGenLock );