Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
04e6d3b8
Commit
04e6d3b8
authored
May 11, 2015
by
Robert Haas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Even when autovacuum=off, force it for members as we do in other cases.
Thomas Munro, with some adjustments by me.
parent
f6a6c46d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
52 additions
and
9 deletions
+52
-9
src/backend/access/transam/multixact.c
src/backend/access/transam/multixact.c
+52
-9
No files found.
src/backend/access/transam/multixact.c
View file @
04e6d3b8
...
...
@@ -204,6 +204,7 @@ typedef struct MultiXactStateData
*/
MultiXactId
oldestMultiXactId
;
Oid
oldestMultiXactDB
;
MultiXactOffset
oldestOffset
;
/*
* This is what the previous checkpoint stored as the truncate position.
...
...
@@ -954,14 +955,17 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset)
* against catastrophic data loss due to multixact wraparound. The basic
* rules are:
*
* If we're past multiVacLimit, start trying to force autovacuum cycles.
* If we're past multiVacLimit or the safe threshold for member storage space,
* start trying to force autovacuum cycles.
* If we're past multiWarnLimit, start issuing warnings.
* If we're past multiStopLimit, refuse to create new MultiXactIds.
*
* Note these are pretty much the same protections in GetNewTransactionId.
*----------
*/
if
(
!
MultiXactIdPrecedes
(
result
,
MultiXactState
->
multiVacLimit
))
if
(
!
MultiXactIdPrecedes
(
result
,
MultiXactState
->
multiVacLimit
)
||
(
MultiXactState
->
nextOffset
-
MultiXactState
->
oldestOffset
>
MULTIXACT_MEMBER_SAFE_THRESHOLD
))
{
/*
* For safety's sake, we release MultiXactGenLock while sending
...
...
@@ -2142,6 +2146,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
MultiXactId
multiStopLimit
;
MultiXactId
multiWrapLimit
;
MultiXactId
curMulti
;
MultiXactOffset
oldestOffset
;
MultiXactOffset
nextOffset
;
Assert
(
MultiXactIdIsValid
(
oldest_datminmxid
));
...
...
@@ -2194,6 +2200,35 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
if
(
multiVacLimit
<
FirstMultiXactId
)
multiVacLimit
+=
FirstMultiXactId
;
/*
* Determine the offset of the oldest multixact that might still be
* referenced. Normally, we can read the offset from the multixact itself,
* but there's an important special case: if there are no multixacts in
* existence at all, oldest_datminmxid obviously can't point to one. It
* will instead point to the multixact ID that will be assigned the next
* time one is needed.
*
* NB: oldest_dataminmxid is the oldest multixact that might still be
* referenced from a table, unlike in DetermineSafeOldestOffset, where we
* do this same computation based on the oldest value that might still
* exist in the SLRU. This is because here we're trying to compute a
* threshold for activating autovacuum, which can only remove references
* to multixacts, whereas there we are computing a threshold for creating
* new multixacts, which requires the old ones to have first been
* truncated away by a checkpoint.
*/
LWLockAcquire
(
MultiXactGenLock
,
LW_SHARED
);
if
(
MultiXactState
->
nextMXact
==
oldest_datminmxid
)
{
oldestOffset
=
MultiXactState
->
nextOffset
;
LWLockRelease
(
MultiXactGenLock
);
}
else
{
LWLockRelease
(
MultiXactGenLock
);
oldestOffset
=
find_multixact_start
(
oldest_datminmxid
);
}
/* Grab lock for just long enough to set the new limit values */
LWLockAcquire
(
MultiXactGenLock
,
LW_EXCLUSIVE
);
MultiXactState
->
oldestMultiXactId
=
oldest_datminmxid
;
...
...
@@ -2202,7 +2237,9 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
MultiXactState
->
multiWarnLimit
=
multiWarnLimit
;
MultiXactState
->
multiStopLimit
=
multiStopLimit
;
MultiXactState
->
multiWrapLimit
=
multiWrapLimit
;
MultiXactState
->
oldestOffset
=
oldestOffset
;
curMulti
=
MultiXactState
->
nextMXact
;
nextOffset
=
MultiXactState
->
nextOffset
;
LWLockRelease
(
MultiXactGenLock
);
/* Log the info */
...
...
@@ -2217,7 +2254,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
* database, it'll call here, and we'll signal the postmaster to start
* another iteration immediately if there are still any old databases.
*/
if
(
MultiXactIdPrecedes
(
multiVacLimit
,
curMulti
)
&&
if
((
MultiXactIdPrecedes
(
multiVacLimit
,
curMulti
)
||
(
nextOffset
-
oldestOffset
>
MULTIXACT_MEMBER_SAFE_THRESHOLD
))
&&
IsUnderPostmaster
&&
!
InRecovery
)
SendPostmasterSignal
(
PMSIGNAL_START_AUTOVAC_LAUNCHER
);
...
...
@@ -2476,11 +2514,16 @@ DetermineSafeOldestOffset(MultiXactId oldestMXact)
MultiXactOffset
oldestOffset
;
/*
* We determine the safe upper bound for offsets of new xacts by reading
* the offset of the oldest multixact, and going back one segment. This
* way, the sequence of multixact member segments will always have a
* one-segment hole at a minimum. We start spewing warnings a few
* complete segments before that.
* Determine the offset of the oldest multixact. Normally, we can read
* the offset from the multixact itself, but there's an important special
* case: if there are no multixacts in existence at all, oldestMXact
* obviously can't point to one. It will instead point to the multixact
* ID that will be assigned the next time one is needed.
*
* NB: oldestMXact should be the oldest multixact that still exists in
* the SLRU, unlike in SetMultiXactIdLimit, where we do this same
* computation based on the oldest value that might be referenced in a
* table.
*/
LWLockAcquire
(
MultiXactGenLock
,
LW_SHARED
);
if
(
MultiXactState
->
nextMXact
==
oldestMXact
)
...
...
@@ -2594,9 +2637,9 @@ ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members)
nextOffset
=
MultiXactState
->
nextOffset
;
oldestMultiXactId
=
MultiXactState
->
oldestMultiXactId
;
nextMultiXactId
=
MultiXactState
->
nextMXact
;
oldestOffset
=
MultiXactState
->
oldestOffset
;
LWLockRelease
(
MultiXactGenLock
);
oldestOffset
=
find_multixact_start
(
oldestMultiXactId
);
*
members
=
nextOffset
-
oldestOffset
;
*
multixacts
=
nextMultiXactId
-
oldestMultiXactId
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment