postgresql/src/backend
Michael Paquier ccfbd9287d Replace existing durable_rename_excl() calls with durable_rename()
durable_rename_excl() attempts to avoid overwriting any existing files
by using link() and unlink(), falling back to rename() on some platforms
(e.g., Windows where link() followed by unlink() is not concurrent-safe,
see 909b449).  Most callers of durable_rename_excl() use it just in case
there is an existing file, but it happens that for all of them we never
expect a target file to exist (WAL segment recycling, creation of
timeline history file and basic_archive).

basic_archive used durable_rename_excl() to avoid overwriting an archive
concurrently created by another server.  Now, there is a stat() call to
avoid overwriting an existing archive a couple of lines above, so note
that this change opens a small TOCTOU window in this module between the
stat() call and durable_rename().

Furthermore, as mentioned in the top comment of durable_rename_excl(),
this routine can result in multiple hard links to the same file and data
corruption, with two or more links to the same file in pg_wal/ if a
crash happens before the unlink() call during WAL recycling.
Specifically, this would produce links to the same file for the current
WAL file and the next one because the half-recycled WAL file was
re-recycled during crash recovery of a follow-up cluster restart.

This change replaces all calls to durable_rename_excl() with
durable_rename().  This removes the protection against accidentally
overwriting an existing file, but some platforms are already living
without it, and all those code paths never expect an existing file (a
couple of assertions are added to check after that, in case).

This is a bug fix, but knowing the unlikeliness of the problem involving
one of more crashes at an exceptionally bad moment, no backpatch is
done.  This could be revisited in the future.

Author: Nathan Bossart
Reviewed-by: Robert Haas, Kyotaro Horiguchi, Michael Paquier
Discussion: https://postgr.es/m/20220407182954.GA1231544@nathanxps13
2022-04-28 10:11:45 +09:00
..
access Replace existing durable_rename_excl() calls with durable_rename() 2022-04-28 10:11:45 +09:00
bootstrap pg_upgrade: Preserve relfilenodes and tablespace OIDs. 2022-01-17 13:40:27 -05:00
catalog Rethink method for assigning OIDs to the template0 and postgres DBs. 2022-04-21 16:23:15 -04:00
commands Always pfree strings returned by GetDatabasePath 2022-04-25 10:32:13 +02:00
executor Fix incorrect format placeholders 2022-04-27 09:49:10 +02:00
foreign Create routine able to set single-call SRFs for Materialize mode 2022-03-07 10:26:29 +09:00
jit Remove extraneous blank lines before block-closing braces 2022-04-13 19:16:02 +02:00
lib dshash: revise sequential scan support. 2022-04-04 14:32:52 -07:00
libpq Remove extraneous blank lines before block-closing braces 2022-04-13 19:16:02 +02:00
main Fix collection of typos in the code and the documentation 2022-03-15 11:29:35 +09:00
nodes Handle NULL fields in WRITE_INDEX_ARRAY 2022-04-27 09:15:09 +02:00
optimizer Remove inadequate assertion check in CTE inlining. 2022-04-21 17:58:52 -04:00
parser Avoid invalid array reference in transformAlterTableStmt(). 2022-04-18 12:16:45 -04:00
partitioning Refactor and cleanup runtime partition prune code a little 2022-04-05 11:46:48 +02:00
po Translation updates 2021-06-21 12:33:50 +02:00
port Ensure that the argument of shmdt(2) is declared "void *". 2022-02-15 17:17:28 -05:00
postmaster Remove extraneous blank lines before block-closing braces 2022-04-13 19:16:02 +02:00
regex Call pg_newlocale_from_collation() also with default collation 2022-01-20 09:50:18 +01:00
replication Remove duplicated word in comment of basebackup.c 2022-04-20 11:05:34 +09:00
rewrite Fix incautious CTE matching in rewriteSearchAndCycle(). 2022-04-23 12:16:12 -04:00
snowball Update copyright for 2022 2022-01-07 19:04:57 -05:00
statistics Remove extraneous blank lines before block-closing braces 2022-04-13 19:16:02 +02:00
storage Tighten ComputeXidHorizons' handling of walsenders. 2022-04-15 17:50:05 -04:00
tcop Remove extraneous blank lines before block-closing braces 2022-04-13 19:16:02 +02:00
tsearch Remove extraneous blank lines before block-closing braces 2022-04-13 19:16:02 +02:00
utils Fix incorrect format placeholders 2022-04-27 09:49:10 +02:00
.gitignore Add .gitignore entries for AIX-specific intermediate build artifacts. 2015-07-08 20:44:22 -04:00
common.mk Remove PARTIAL_LINKING build mode. 2018-03-30 17:33:04 -07:00
Makefile Server-side gzip compression. 2022-01-24 15:13:18 -05:00
nls.mk Report progress of startup operations that take a long time. 2021-10-25 11:51:57 -04:00