Re: odd buildfarm failure - "pg_ctl: control file appears to be corrupt"
Thomas Munro <thomas.munro@gmail.com>
From: Thomas Munro <thomas.munro@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Andres Freund <andres@anarazel.de>, pgsql-hackers@postgresql.org
Date: 2022-11-24T01:02:54Z
Lists: pgsql-hackers
Attachments
- 0001-XXX-Dirty-hack-to-clobber-control-file-for-testing.patch (text/x-patch) patch 0001
- 0002-Try-to-tolerate-concurrent-reads-and-writes-of-contr.patch (text/x-patch) patch 0002
On Thu, Nov 24, 2022 at 11:05 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > Thomas Munro <thomas.munro@gmail.com> writes: > > On Wed, Nov 23, 2022 at 11:03 PM Thomas Munro <thomas.munro@gmail.com> wrote: > > As for what to do about it, some ideas: > > 2. Retry after a short time on checksum failure. The probability is > > already miniscule, and becomes pretty close to 0 if we read thrice > > 100ms apart. > > > First thought is that 2 is appropriate level of complexity for this > > rare and stupid problem. > > Yeah, I was thinking the same. A variant could be "repeat until > we see the same calculated checksum twice". Hmm. While writing a comment to explain why that's good enough, I realised it's not really true for a standby that control file writes are always expected to be far apart in time. XLogFlush-> UpdateMinRecoveryPoint() could coincide badly with our N attempts for any small N and for any nap time, which I think makes your idea better than mine. With some cartoon-level understanding of what's going on (to wit: I think the kernel just pins the page but doesn't use a page-level content lock or range lock, so what you're seeing is raw racing memcpy calls and unsynchronised cache line effects), I guess you'd be fairly likely to make "progress" in seeing more new data even if you didn't sleep in between, but who knows. So I have a 10ms sleep to make progress very likely; given your algorithm it doesn't matter if you didn't make all the progress, just some. Since this is reachable from SQL, I think we also need a CFI call so you can't get uninterruptibly stuck here? I wrote a stupid throw-away function to force a write. If you have an ext4 system to hand (xfs, zfs, apfs, ufs, others don't suffer from this) you can do: do $$ begin for i in 1..100000000 do loop perform pg_update_control_file(); end loop; end; $$; ... while you also do: select pg_control_system(); \watch 0.001 ... and you'll soon see: ERROR: calculated CRC checksum does not match value stored in file The attached draft patch fixes it.
Commits
-
Try to handle torn reads of pg_control in frontend.
- 63a582222c6b 17.0 landed
- 43c979086825 12.17 landed
- 67060be3df34 13.13 landed
- dc75748a918e 14.10 landed
- 5e39884d322a 15.5 landed
- 5725e4ebe7a9 16.1 landed
-
Acquire ControlFileLock in relevant SQL functions.
- f1634c968101 11.22 landed
- 637e86ecc5e4 12.17 landed
- ae9da357bd6d 13.13 landed
- a56fe5cf07fe 14.10 landed
- 606be8a35d97 15.5 landed
- 2371432cd6b9 16.1 landed
- c558e6fd92ff 17.0 landed