Re: effective_multixact_freeze_max_age issue
Peter Geoghegan <pg@bowt.ie>
From: Peter Geoghegan <pg@bowt.ie>
To: "Anton A. Melnikov" <aamelnikov@inbox.ru>
Cc: Nathan Bossart <nathandbossart@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>,
Thomas Munro <thomas.munro@gmail.com>, Robert Haas <robertmhaas@gmail.com>, "Bossart, Nathan" <bossartn@amazon.com>, Jeremy Schneider <schneider@ardentperf.com>
Date: 2022-10-24T14:56:24Z
Lists: pgsql-hackers
On Mon, Oct 24, 2022 at 1:18 AM Anton A. Melnikov <aamelnikov@inbox.ru> wrote: > > Also, the proposed new WARNING is only seen when we're > > bound to also see the existing OldestXmin WARNING already. Why have 2 > > WARNINGs about exactly the same problem?> > > I didn't understand this moment. > > If the FreezeLimit is always older than OldestXmin or equal to it according to: > > > FreezeLimit is usually 50 million XIDs before > > OldestXmin (the freeze_min_age default), > > can't there be a situation like this? I don't understand what you mean. FreezeLimit *isn't* always exactly 50 million XIDs before OldestXmin -- not anymore. In fact that's the main benefit of this work (commit c3ffa731). That detail has changed (and changed for the better). Though it will only be noticeable to users when an old snapshot holds back OldestXmin by a significant amount. It is true that we must always respect the classic "FreezeLimit <= OldestXmin" invariant. So naturally vacuum_set_xid_limits() continues to make sure that the invariant holds in all cases, if necessary by holding back FreezeLimit: + /* freezeLimit must always be <= oldestXmin */ + if (TransactionIdPrecedes(*oldestXmin, *freezeLimit)) + *freezeLimit = *oldestXmin; When we *don't* have to do this (very typical when vacuum_freeze_min_age is set to its default of 50 million), then FreezeLimit won't be affected by old snapshots. Overall, FreezeLimit must either be: 1. *Exactly* freeze_min_age XIDs before nextXID (note that it is nextXID instead of OldestXmin here, as of commit c3ffa731). or: 2. *Exactly* OldestXmin. FreezeLimit must always be either exactly 1 or exactly 2, regardless of anything else (like long running transactions/snapshots). Importantly, we still never interpret freeze_min_age as more than "autovacuum_freeze_max_age / 2" when determining FreezeLimit. While the safeOldestXmin cutoff is "nextXID - autovacuum_freeze_max_age". Before commit c3ffa731, FreezeLimit would sometimes be interpreted as exactly OldestXmin -- it would be set to OldestXmin directly when the WARNING was given. But now we get smoother behavior, without any big discontinuities in how FreezeLimit is set over time when OldestXmin is held back generally. -- Peter Geoghegan
Commits
-
Derive freeze cutoff from nextXID, not OldestXmin.
- c3ffa731a5f9 16.0 landed
-
Consolidate VACUUM xid cutoff logic.
- efa4a9462a07 15.0 cited
-
Fix bug that could try to freeze running multixacts.
- 6bda2af039d4 13.0 cited
-
Teach autovacuum about multixact member wraparound.
- 53bb309d2d5a 9.5.0 cited