Re: BUG #17949: Adding an index introduces serialisation anomalies.
Thomas Munro <thomas.munro@gmail.com>
From: Thomas Munro <thomas.munro@gmail.com>
To: Dmitry Dolgov <9erthalion6@gmail.com>
Cc: artem.anisimov.255@gmail.com, pgsql-bugs@lists.postgresql.org, Teodor Sigaev <teodor@sigaev.ru>, Heikki Linnakangas <hlinnaka@iki.fi>
Date: 2023-06-26T00:25:14Z
Lists: pgsql-bugs
Attachments
- v3-0001-Fix-race-in-SSI-interaction-with-empty-btrees.patch (text/x-patch) patch v3-0001
- v3-0002-Fix-race-in-SSI-interaction-with-bitmap-heap-scan.patch (text/x-patch) patch v3-0002
- v3-0003-Fix-race-in-SSI-interaction-with-gin-fast-path.patch (text/x-patch) patch v3-0003
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?
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