Re: Catalog invalidations vs catalog scans vs ScanPgRelation()
Andres Freund <andres@anarazel.de>
From: Andres Freund <andres@anarazel.de>
To: pgsql-hackers@postgresql.org, Robert Haas <robertmhaas@gmail.com>
Date: 2020-03-28T20:54:10Z
Lists: pgsql-hackers
Attachments
Hi, On 2020-03-28 12:30:40 -0700, Andres Freund wrote: > On 2020-02-28 22:10:52 -0800, Andres Freund wrote: > > On 2020-02-28 21:24:59 -0800, Andres Freund wrote: > > So, um. What happens is that doDeletion() does a catalog scan, which > > sets a snapshot. The results of that catalog scan are then used to > > perform modifications. But at that point there's no guarantee that we > > still hold *any* snapshot, as e.g. invalidations can trigger the catalog > > snapshot being released. > > > > I don't see how that's safe. Without ->xmin preventing that, > > intermediate row versions that we did look up could just get vacuumed > > away, and replaced with a different row. That does seem like a serious > > issue? > > > > I think there's likely a lot of places that can hit this? What makes it > > safe for InvalidateCatalogSnapshot()->SnapshotResetXmin() to release > > ->xmin when there previously has been *any* catalog access? Because in > > contrast to normal table modifications, there's currently nothing at all > > forcing us to hold a snapshot between catalog lookups an their > > modifications? > > > > Am I missing something? Or is this a fairly significant hole in our > > arrangements? > > > > The easiest way to fix this would probably be to have inval.c call a > > version of InvalidateCatalogSnapshot() that leaves the oldest catalog > > snapshot around, but sets up things so that GetCatalogSnapshot() will > > return a freshly taken snapshot? ISTM that pretty much every > > InvalidateCatalogSnapshot() call within a transaction needs that behaviour? > > I'd still like to get some input here. Attached is a one patch that adds assertions to detect this, and one that puts enough workarounds in place to make the tests pass. I don't like this much, but I thought it'd be useful for others to understand the problem. Greetings, Andres Freund
Commits
-
Ensure snapshot is registered within ScanPgRelation().
- 42750b08d946 13.0 landed
- 820f21a93f0b 9.5.22 landed
- 211d8f65392f 9.6.18 landed
- a0e2a178c640 10.13 landed
- 00a0a428ef50 11.8 landed
- 1d377f203ea4 12.3 landed