Re: post-recovery amcheck expectations
Noah Misch <noah@leadboat.com>
From: Noah Misch <noah@leadboat.com>
To: Peter Geoghegan <pg@bowt.ie>
Cc: pgsql-hackers@postgresql.org, Alexander Korotkov <aekorotkov@gmail.com>
Date: 2023-10-25T03:04:59Z
Lists: pgsql-hackers
On Tue, Oct 24, 2023 at 07:03:34PM -0700, Peter Geoghegan wrote: > On Mon, Oct 23, 2023 at 7:28 PM Noah Misch <noah@leadboat.com> wrote: > > > That makes sense to me. I believe that it's not possible to have a > > > string of consecutive sibling pages that are all half-dead (regardless > > > of the BlockNumber order of sibling pages, even). But I'd probably > > > have written the fix in roughly the same way. Although...maybe you > > > should try to detect a string of half-dead pages? Hard to say if it's > > > worth the trouble. > > > > I imagined a string of half-dead siblings could arise in structure like this: > > > > * 1 > > * / | \ > > * 4 <-> 2 <-> 3 > > > > With events like this: > > > > - DELETE renders blk 4 deletable. > > - Crash with concurrent VACUUM, leaving 4 half-dead after having visited 1-4. > > - DELETE renders blk 2 deletable. > > - Crash with concurrent VACUUM, leaving 2 half-dead after having visited 1-2. > > > > I didn't try to reproduce that, and something may well prevent it. > > FWIW a couple of factors prevent it (in the absence of corruption). These are: > > 1. Only VACUUM can delete pages, and in general the only possible > source of half-dead pages is an unfortunately timed crash/error within > VACUUM. Each interrupted VACUUM can leave behind at most one half-dead > page. Agreed. > 2. One thing that makes VACUUM back out of deleting an empty page is > the presence of a half-dead right sibling leaf page left behind by > some VACUUM that was interrupted at some point in the past -- see > _bt_rightsib_halfdeadflag() for details. > > Obviously, factors 1 and 2 together make three consecutive half-dead > sibling pages impossible. Can't it still happen if the sequence of unfortunately timed crashes causes deletions from left to right? Take this example, expanding the one above. Half-kill 4, crash, half-kill 3, crash, half-kill 2 in: * 1 * / / | \ \ * 4 <-> 3 <-> 2 <-> 1 (That's not to say it has ever happened outside of a test.)
Commits
-
amcheck: Distinguish interrupted page deletion from corruption.
- f31ccb575ed6 13.13 landed
- e04509f3246d 11.22 landed
- 42496cba60bc 14.10 landed
- 3a205c91665f 12.17 landed
- 6f81386a9cea 15.5 landed
- 3c6a05b805c7 16.1 landed
- 6ec9e9975eff 17.0 landed
-
Improve checking of child pages in contrib/amcheck.
- d114cc538715 13.0 cited