Commit 6bda2af0 authored by Thomas Munro's avatar Thomas Munro

Fix bug that could try to freeze running multixacts.

Commits 801c2dc7 and 801c2dc7 made it possible for vacuum to
try to freeze a multixact that is still running.  That was
prevented by a check, but raised an error.  Repair.

Back-patch all the way.

Author: Nathan Bossart, Jeremy Schneider
Reported-by: Jeremy Schneider
Reviewed-by: Jim Nasby, Thomas Munro
Discussion: https://postgr.es/m/DAFB8AFF-2F05-4E33-AD7F-FF8B0F760C17%40amazon.com
parent 0d21f919
...@@ -893,6 +893,7 @@ vacuum_set_xid_limits(Relation rel, ...@@ -893,6 +893,7 @@ vacuum_set_xid_limits(Relation rel,
int effective_multixact_freeze_max_age; int effective_multixact_freeze_max_age;
TransactionId limit; TransactionId limit;
TransactionId safeLimit; TransactionId safeLimit;
MultiXactId oldestMxact;
MultiXactId mxactLimit; MultiXactId mxactLimit;
MultiXactId safeMxactLimit; MultiXactId safeMxactLimit;
...@@ -970,7 +971,8 @@ vacuum_set_xid_limits(Relation rel, ...@@ -970,7 +971,8 @@ vacuum_set_xid_limits(Relation rel,
Assert(mxid_freezemin >= 0); Assert(mxid_freezemin >= 0);
/* compute the cutoff multi, being careful to generate a valid value */ /* compute the cutoff multi, being careful to generate a valid value */
mxactLimit = GetOldestMultiXactId() - mxid_freezemin; oldestMxact = GetOldestMultiXactId();
mxactLimit = oldestMxact - mxid_freezemin;
if (mxactLimit < FirstMultiXactId) if (mxactLimit < FirstMultiXactId)
mxactLimit = FirstMultiXactId; mxactLimit = FirstMultiXactId;
...@@ -984,7 +986,11 @@ vacuum_set_xid_limits(Relation rel, ...@@ -984,7 +986,11 @@ vacuum_set_xid_limits(Relation rel,
ereport(WARNING, ereport(WARNING,
(errmsg("oldest multixact is far in the past"), (errmsg("oldest multixact is far in the past"),
errhint("Close open transactions with multixacts soon to avoid wraparound problems."))); errhint("Close open transactions with multixacts soon to avoid wraparound problems.")));
mxactLimit = safeMxactLimit; /* Use the safe limit, unless an older mxact is still running */
if (MultiXactIdPrecedes(oldestMxact, safeMxactLimit))
mxactLimit = oldestMxact;
else
mxactLimit = safeMxactLimit;
} }
*multiXactCutoff = mxactLimit; *multiXactCutoff = mxactLimit;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment