Re: BUG #17949: Adding an index introduces serialisation anomalies.
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Thomas Munro <thomas.munro@gmail.com>,
Dmitry Dolgov <9erthalion6@gmail.com>
Cc: artem.anisimov.255@gmail.com, pgsql-bugs@lists.postgresql.org,
Teodor Sigaev <teodor@sigaev.ru>
Date: 2023-06-26T08:04:26Z
Lists: pgsql-bugs
On 26/06/2023 03:25, Thomas Munro wrote: > On Sun, Jun 25, 2023 at 1:59 AM Dmitry Dolgov <9erthalion6@gmail.com> wrote: >> I've managed to resolve it, or at least reduce the chances for the issue to >> appear, via semi-randomly adding more CheckForSerializableConflictIn / >> PredicateLock around the new sublist that has to be created in >> ginHeapTupleFastInsert. I haven't seen the reproducer failing with this >> changeset after running it multiple times for a couple of minutes, where on the >> main branch, with the two fixes from Thomas included, it was failing within a >> couple of seconds. > > Ahh, right, thanks. I don't think we need to lock all those pages as > you showed, as this whole "fast" path is supposed to be covered by the > meta page (in other words, GIN is expected to have the highest > possible serialisation failure rate under SSI unless you turn fast > updates off). But there is an ordering bug with the existing > predicate lock in that code, which allows this to happen: > > S1: CheckForSerializableConflictIn(meta) > > S2: PredicateLockPage(meta) > S2: scan, find no tuples > > S1: BufferLock(EXCLUSIVE > S1: modify stuff... > > CheckForSerializableConflictIn() was written with the assumption that > you're inserting a tuple (ie you have the page containing the tuple > locked), so you'll either conflict with a reader who already has a > predicate lock at that point OR you'll insert first and then the > reader will see your (invisible-to-snapshot) tuples, but here we're > doing some fancy footwork with a meta page, and we screwed up the > ordering and left a window where neither of those things happens. > Perhaps it was coded that way because there is drop-then-reacquire > dance, but it's easy enough to move the check in both branches. Does > that make sense? Yes, +1 on the patches. Any chance of constructing test cases for these? The above race condition is hard to reach, but some of these other bugs seem more testable. Some minor nits: In v3-0001-Fix-race-in-SSI-interaction-with-empty-btrees.patch: > /* > - * We only get here if the index is completely empty. Lock relation > - * because nothing finer to lock exists. > + * Since we have no pages locked, it's possible for another > + * transaction to insert data between _bt_search() and > + * PredicateLockRelation(). We have to try again after taking a > + * relation-level predicate lock, to close a narrow window where we > + * wouldn't scan concurrently inserted tuples, but the writer wouldn't > + * see our predicate lock. > */ I'd like to keep the old comment here, it's good context, and add the new text in addition to the old. v3-0002-Fix-race-in-SSI-interaction-with-bitmap-heap-scan.patch: Can we keep the optimization when not using SSI? -- Heikki Linnakangas Neon (https://neon.tech)
Commits
-
Fix race in SSI interaction with bitmap heap scan.
- 814f3c8e4868 11.21 landed
- 17b8887c29e5 12.16 landed
- 8976ac5c5c00 13.12 landed
- 3f7d3a77e18d 14.9 landed
- ab265e98500b 15.4 landed
- bcc93a389ce3 17.0 landed
- d03d9a2614fd 16.0 landed
-
Fix race in SSI interaction with gin fast path.
- 13f127800fed 11.21 landed
- 255a925d333b 12.16 landed
- fc15473840bc 13.12 landed
- fb663f38790e 14.9 landed
- d34aa0a2f4f3 15.4 landed
- 126552c85c1c 17.0 landed
- 12529028a4e5 16.0 landed
-
Fix race in SSI interaction with empty btrees.
- 0048c3b51549 11.21 landed
- fe88497b4d0b 12.16 landed
- 8f705d7b9d01 13.12 landed
- ae6d536ed0dc 14.9 landed
- 0f275b0ee8e4 15.4 landed
- f9b7fc651a99 17.0 landed
- 0cb1fb2c9bf8 16.0 landed
-
Re-think predicate locking on GIN indexes.
- 0bef1c0678d9 11.0 cited