Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit04e6d3b

Browse files
committed
Even when autovacuum=off, force it for members as we do in other cases.
Thomas Munro, with some adjustments by me.
1 parentf6a6c46 commit04e6d3b

File tree

1 file changed

+52
-9
lines changed

1 file changed

+52
-9
lines changed

‎src/backend/access/transam/multixact.c

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ typedef struct MultiXactStateData
204204
*/
205205
MultiXactIdoldestMultiXactId;
206206
OidoldestMultiXactDB;
207+
MultiXactOffsetoldestOffset;
207208

208209
/*
209210
* This is what the previous checkpoint stored as the truncate position.
@@ -954,14 +955,17 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset)
954955
* against catastrophic data loss due to multixact wraparound. The basic
955956
* rules are:
956957
*
957-
* If we're past multiVacLimit, start trying to force autovacuum cycles.
958+
* If we're past multiVacLimit or the safe threshold for member storage space,
959+
* start trying to force autovacuum cycles.
958960
* If we're past multiWarnLimit, start issuing warnings.
959961
* If we're past multiStopLimit, refuse to create new MultiXactIds.
960962
*
961963
* Note these are pretty much the same protections in GetNewTransactionId.
962964
*----------
963965
*/
964-
if (!MultiXactIdPrecedes(result,MultiXactState->multiVacLimit))
966+
if (!MultiXactIdPrecedes(result,MultiXactState->multiVacLimit)||
967+
(MultiXactState->nextOffset-MultiXactState->oldestOffset
968+
>MULTIXACT_MEMBER_SAFE_THRESHOLD))
965969
{
966970
/*
967971
* For safety's sake, we release MultiXactGenLock while sending
@@ -2142,6 +2146,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
21422146
MultiXactIdmultiStopLimit;
21432147
MultiXactIdmultiWrapLimit;
21442148
MultiXactIdcurMulti;
2149+
MultiXactOffsetoldestOffset;
2150+
MultiXactOffsetnextOffset;
21452151

21462152
Assert(MultiXactIdIsValid(oldest_datminmxid));
21472153

@@ -2194,6 +2200,35 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
21942200
if (multiVacLimit<FirstMultiXactId)
21952201
multiVacLimit+=FirstMultiXactId;
21962202

2203+
/*
2204+
* Determine the offset of the oldest multixact that might still be
2205+
* referenced. Normally, we can read the offset from the multixact itself,
2206+
* but there's an important special case: if there are no multixacts in
2207+
* existence at all, oldest_datminmxid obviously can't point to one. It
2208+
* will instead point to the multixact ID that will be assigned the next
2209+
* time one is needed.
2210+
*
2211+
* NB: oldest_dataminmxid is the oldest multixact that might still be
2212+
* referenced from a table, unlike in DetermineSafeOldestOffset, where we
2213+
* do this same computation based on the oldest value that might still
2214+
* exist in the SLRU. This is because here we're trying to compute a
2215+
* threshold for activating autovacuum, which can only remove references
2216+
* to multixacts, whereas there we are computing a threshold for creating
2217+
* new multixacts, which requires the old ones to have first been
2218+
* truncated away by a checkpoint.
2219+
*/
2220+
LWLockAcquire(MultiXactGenLock,LW_SHARED);
2221+
if (MultiXactState->nextMXact==oldest_datminmxid)
2222+
{
2223+
oldestOffset=MultiXactState->nextOffset;
2224+
LWLockRelease(MultiXactGenLock);
2225+
}
2226+
else
2227+
{
2228+
LWLockRelease(MultiXactGenLock);
2229+
oldestOffset=find_multixact_start(oldest_datminmxid);
2230+
}
2231+
21972232
/* Grab lock for just long enough to set the new limit values */
21982233
LWLockAcquire(MultiXactGenLock,LW_EXCLUSIVE);
21992234
MultiXactState->oldestMultiXactId=oldest_datminmxid;
@@ -2202,7 +2237,9 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
22022237
MultiXactState->multiWarnLimit=multiWarnLimit;
22032238
MultiXactState->multiStopLimit=multiStopLimit;
22042239
MultiXactState->multiWrapLimit=multiWrapLimit;
2240+
MultiXactState->oldestOffset=oldestOffset;
22052241
curMulti=MultiXactState->nextMXact;
2242+
nextOffset=MultiXactState->nextOffset;
22062243
LWLockRelease(MultiXactGenLock);
22072244

22082245
/* Log the info */
@@ -2217,7 +2254,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
22172254
* database, it'll call here, and we'll signal the postmaster to start
22182255
* another iteration immediately if there are still any old databases.
22192256
*/
2220-
if (MultiXactIdPrecedes(multiVacLimit,curMulti)&&
2257+
if ((MultiXactIdPrecedes(multiVacLimit,curMulti)||
2258+
(nextOffset-oldestOffset>MULTIXACT_MEMBER_SAFE_THRESHOLD))&&
22212259
IsUnderPostmaster&& !InRecovery)
22222260
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
22232261

@@ -2476,11 +2514,16 @@ DetermineSafeOldestOffset(MultiXactId oldestMXact)
24762514
MultiXactOffsetoldestOffset;
24772515

24782516
/*
2479-
* We determine the safe upper bound for offsets of new xacts by reading
2480-
* the offset of the oldest multixact, and going back one segment. This
2481-
* way, the sequence of multixact member segments will always have a
2482-
* one-segment hole at a minimum. We start spewing warnings a few
2483-
* complete segments before that.
2517+
* Determine the offset of the oldest multixact. Normally, we can read
2518+
* the offset from the multixact itself, but there's an important special
2519+
* case: if there are no multixacts in existence at all, oldestMXact
2520+
* obviously can't point to one. It will instead point to the multixact
2521+
* ID that will be assigned the next time one is needed.
2522+
*
2523+
* NB: oldestMXact should be the oldest multixact that still exists in
2524+
* the SLRU, unlike in SetMultiXactIdLimit, where we do this same
2525+
* computation based on the oldest value that might be referenced in a
2526+
* table.
24842527
*/
24852528
LWLockAcquire(MultiXactGenLock,LW_SHARED);
24862529
if (MultiXactState->nextMXact==oldestMXact)
@@ -2594,9 +2637,9 @@ ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members)
25942637
nextOffset=MultiXactState->nextOffset;
25952638
oldestMultiXactId=MultiXactState->oldestMultiXactId;
25962639
nextMultiXactId=MultiXactState->nextMXact;
2640+
oldestOffset=MultiXactState->oldestOffset;
25972641
LWLockRelease(MultiXactGenLock);
25982642

2599-
oldestOffset=find_multixact_start(oldestMultiXactId);
26002643
*members=nextOffset-oldestOffset;
26012644
*multixacts=nextMultiXactId-oldestMultiXactId;
26022645
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp