Re: avoid multiple hard links to same WAL file after a crash
Michael Paquier <michael@paquier.xyz>
On Tue, Apr 12, 2022 at 09:27:42AM -0700, Nathan Bossart wrote: > On Tue, Apr 12, 2022 at 03:46:31PM +0900, Kyotaro Horiguchi wrote: >> At Mon, 11 Apr 2022 09:52:57 -0700, Nathan Bossart <nathandbossart@gmail.com> wrote in >>> I traced this back a while ago. I believe the link() was first added in >>> November 2000 as part of f0e37a8. This even predates WAL recycling, which >>> was added in July 2001 as part of 7d4d5c0. >> >> f0e37a8 lacks discussion.. It introduced the CHECKPOINT command from >> somwhere out of the ML.. This patch changed XLogFileInit to >> supportusing existent files so that XLogWrite can use the new segment >> provided by checkpoint and still allow XLogWrite to create a new >> segment by itself. Yes, I think that you are right here. I also suspect that the checkpoint command was facing a concurrency issue while working on the feature and that Vadim saw that this part of the implementation would be safer in the long run if we use link() followed by unlink(). > Yeah, I've been unable to find any discussion besides a brief reference to > adding checkpointing [0]. > > [0] https://postgr.es/m/8F4C99C66D04D4118F580090272A7A23018D85%40sectorbase1.sectorbase.com While looking at the history of this area, I have also noticed this argument, telling also that this is a safety measure if this code were to run in parallel, but that's without counting on the control file lock hold while doing this operation anyway: https://www.postgresql.org/message-id/24974.982597735@sss.pgh.pa.us As mentioned already upthread, f0e37a8 is the origin of the link()/unlink() business in the WAL segment initialization logic, and also note 1f159e5 that has added a rename() as extra code path for systems where link() was not working. At the end, switching directly from durable_rename_excl() to durable_rename() should be fine for the WAL segment initialization, but we could do things a bit more carefully by adding a check on the file existence before calling durable_rename() and issue a elog(LOG) if a file is found, giving a mean for the WAL recycling to give up peacefully as it does now. Per my analysis, the TLI history file created at the end of recovery ought to issue an elog(ERROR). Now, I am surprised by the third code path of durable_rename_excl(), as of the WAL receiver doing writeTimeLineHistoryFile(), to not cause any issues, as link() should exit with EEXIST when the startup process grabs the same history file concurrently. It seems to me that in this last case using durable_rename() could be an improvement and prevent extra WAL receiver restarts as a TLI history fetched from the primary via streaming or from some archives should be the same, but we could be more careful, like the WAL init logic, by skipping the durable_rename() and issuing an elog(LOG). That would not be perfect, still a bit better than the current state of HEAD. As we are getting closer to the beta release, it looks safer to let this change aside a bit longer and wait for v16 to be opened for business on HEAD. -- Michael
Commits
-
Test restartpoints in archive recovery.
- 4399d1055627 13.21 landed
- 41ffd9d6a724 14.18 landed
- e297ddcfb7d3 17.5 landed
- 91168a9ae38d 15.13 landed
- 4664de1826a8 16.9 landed
- 714bd9e3a733 18.0 landed
-
Reset InstallXLogFileSegmentActive after walreceiver self-initiated exit.
- 69a498eb6465 13.21 landed
- 3635a0a35aaf 14.18 landed
-
Skip WAL recycling and preallocation during archive recovery.
- a5b0c06daae9 13.21 landed
- 014a508009df 14.18 landed
- cc2c7d65fc27 15.0 cited
-
Don't ERROR on PreallocXlogFiles() race condition.
- cbed472a9341 13.21 landed
- 675b771ca5f2 14.18 landed
-
Revert "Add HINT for restartpoint race with KeepFileRestoredFromArchive()."
- e77d9cd4f52e 13.21 landed
- 47d2d2982729 14.18 landed
-
Remove XLogFileInit() ability to unlink a pre-existing file.
- d0b6acaf04a2 13.21 landed
- b494640e8297 14.18 landed
-
In XLogFileInit(), fix *use_existent postcondition to suit callers.
- 20e5ef3ca70c 13.21 landed
- 8967dddf086e 14.18 landed
-
Remove XLogFileInit() ability to skip ControlFileLock.
- df8ec9634ccd 13.21 landed
- 6b168c1299c5 14.18 landed
-
Replace durable_rename_excl() by durable_rename(), take two
- 26a79cbbdace 13.19 landed
- 1f95181b44c8 14.16 landed
- c1c9df3159cf 15.11 landed
- dac1ff30906b 16.0 landed
-
Add HINT for restartpoint race with KeepFileRestoredFromArchive().
- 8ad6c5dbbe5a 14.5 cited
-
Remove durable_rename_excl()
- eb64ceac7ec3 16.0 landed
- 2c902bbf1911 15.0 landed
-
Replace existing durable_rename_excl() calls with durable_rename()
- ccfbd9287d70 15.0 landed