Skip to content

Commit a037926

Browse files
committed
Reorder code so that we don't have to hold a critical section while
reserving SLRU space for a new MultiXact. The original coding would have treated out-of-disk-space as a PANIC condition, which is unnecessary.
1 parent a7de22d commit a037926

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

src/backend/access/transam/multixact.c

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
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/28 17:27:29 tgl Exp $
45+
* $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.11 2005/10/28 19:00:19 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -630,22 +630,13 @@ CreateMultiXactId(int nxids, TransactionId *xids)
630630
return 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
*/
645638
multi = 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
*/
772766
static MultiXactId
773767
GetNewMultiXactId(int nxids, MultiXactOffset *offset)
@@ -794,18 +788,7 @@ GetNewMultiXactId(int nxids, MultiXactOffset *offset)
794788
ExtendMultiXactOffset(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

821804
ExtendMultiXactMember(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+
823827
MultiXactState->nextOffset += nxids;
824828

825829
LWLockRelease(MultiXactGenLock);

0 commit comments

Comments
 (0)