Hi Shihao,

On 10/25/26 16:36, shihao zhong wrote:
I reproduced all three cases on master with an
injection point, and v1 fixes them.

Thank you for testing!

I confirmed with injection points as well but was not sure it was worth adding them to the patch since the fix is pretty straightforward.

I found one more file with the same problem. A checkpoint rewrites
pg_twophase files in place with O_TRUNC. If the backup copies one
right after the truncate, it gets an empty file.

Good catch. My audit noticed this truncate but failed to note that the file would be accessed before WAL replay reconstructed it.

One small correction: a checkpoint writes each state file only once and then flags the transaction as on disk. The window therefore appears to be between creating the file and finishing the write rather than a truncate of existing contents.

This is not limited to backups. It appears that if the checkpointer is killed between the open and the write, or the OS crashes before the fsync, then the file is left empty or partial and crash recovery fails the same way.

A few notes on the patch:

- A stale .tmp file is never removed. restoreTwoPhaseData() will need to handle this or they will build up.

- There's a double blank line before the rename.

- In the commit message, I think "truncates and rewrites" should be something like "creates and writes".

> v1 cannot help here, since the open file really is empty.

Since v1 can't help here it should probably be a separate patch. Or, we could include it as the first patch in a set with mine. At this point it would be good to get some feedback from a committer to see how they want to proceed.

Minor releases are soon but these bugs are so old that I'm not sure it makes sense to rush.

Also, pg_verifybackup reports all of these broken backups as fine.
This is as expected. pg_verify can only work with the data it was provided. If we fix the upstream code then pg_verify will be fine.

Regards,
-David


Reply via email to