Re: remove spurious CREATE INDEX CONCURRENTLY wait
Alvaro Herrera <alvherre@alvh.no-ip.org>
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Andres Freund <andres@anarazel.de>, Michael Paquier <michael@paquier.xyz>, Dmitry Dolgov <9erthalion6@gmail.com>, James Coleman <jtc331@gmail.com>, Pg Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2020-11-24T21:57:13Z
Lists: pgsql-hackers
On 2020-Nov-23, Tom Lane wrote: > Alvaro Herrera <alvherre@alvh.no-ip.org> writes: > > GetCurrentVirtualXIDs, ComputeXidHorizons, GetSnapshotData: > > > In these cases, what we need is that the code computes some xmin (or > > equivalent computation) based on a set of transactions that exclude > > those marked with the flags. The behavior we want is that if some > > transaction is marked as vacuum, we ignore the Xid/Xmin *if there is > > one*. In other words, if there's no Xid/Xmin, then the flag is not > > important. So if we can ensure that the flag is set first, and the > > Xid/xmin is installed later, that's sufficient correctness and we don't > > need to hold exclusive lock. But if we can't ensure that, then we must > > use exclusive lock, because otherwise we risk another process seeing our > > Xid first and not our flag, which would be bad. > > I don't buy this either. You get the same result if someone looks just > before you take the ProcArrayLock to set the flag. So if there's a > problem, it's inherent in the way that the flags are defined or used; > the strength of lock used in this stanza won't affect it. The problem is that the writes could be reordered in a way that makes the Xid appear set to an onlooker before PROC_IN_VACUUM appears set. Vacuum always sets the bit first, and *then* the xid. If the reader always reads it like that then it's not a problem. But in order to guarantee that, we would have to have a read barrier for each pass through the loop. With the LW_EXCLUSIVE lock, we block the readers so that the bit is known set by the time they examine it. As I understand, getting the lock is itself a barrier, so there's no danger that we'll set the bit and they won't see it. ... at least, that how I *imagine* the argument to be. In practice, vacuum_rel() calls GetSnapshotData() before installing the PROC_IN_VACUUM bit, and therefore there *is* a risk that reader 1 will get MyProc->xmin included in their snapshot (because bit not yet set), and reader 2 won't. If my understanding is correct, then we should move the PushActiveSnapshot(GetTransactionSnapshot()) call to after we have the PROC_IN_VACUUM bit set.
Commits
-
Restore lock level to set vacuum flags
- 9aa91cb33b70 14.2 landed
- 0726c764bc4e 15.0 landed
-
Restore lock level to update statusFlags
- dcfff74fb166 14.0 landed
-
Avoid spurious waits in concurrent indexing
- c98763bf51bf 14.0 landed
-
Centralize logic for skipping useless ereport/elog calls.
- 789b938bf2b8 14.0 landed
-
Don't hold ProcArrayLock longer than needed in rare cases
- 450c8230b1f7 14.0 landed
-
Relax lock level for setting PGPROC->statusFlags
- 27838981be9d 14.0 landed
-
Rename PGPROC->vacuumFlags to statusFlags
- cd9c1b3e197a 14.0 landed
-
snapshot scalability: Move PGXACT->vacuumFlags to ProcGlobal->vacuumFlags.
- 5788e258bb26 14.0 cited
-
Allow an autovacuum worker to be interrupted automatically when it is found
- acac68b2bcae 8.3.0 cited