From f6f4c94c3c291f8b473e7f9048b42c0115331b8a Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Sun, 23 Aug 2026 12:15:15 +0300 Subject: [PATCH v1] Make test WAL archiving publish files atomically --- src/test/perl/PostgreSQL/Test/Cluster.pm | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm index 920d831be9e..da0499ad14b 100644 --- a/src/test/perl/PostgreSQL/Test/Cluster.pm +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -1541,10 +1541,25 @@ sub enable_archiving # first. Paths also need to be double-quoted to prevent failures where # the path contains spaces. $path =~ s{\\}{\\\\}g if ($PostgreSQL::Test::Utils::windows_os); - my $copy_command = - $PostgreSQL::Test::Utils::windows_os - ? qq{copy "%p" "$path\\\\%f"} - : qq{cp "%p" "$path/%f"}; + # Copy to a temporary file in the archive directory, then publish it under + # the name expected by restore_command. In particular, don't leave a + # partially-copied file visible if the archive command is interrupted. + # Generate the suffix here so that all commands use exactly the same name. + my $temp_suffix = sprintf("%08x", int(rand(0x7fffffff))); + my $copy_command; + + if ($PostgreSQL::Test::Utils::windows_os) + { + my $temp_path = "$path\\\\.%f.tmp.$temp_suffix"; + $copy_command = qq{copy /Y "%p" "$temp_path"} + . qq{ && move /Y "$temp_path" "$path\\\\%f"}; + } + else + { + my $temp_path = "$path/.%f.tmp.$temp_suffix.\$\$"; + $copy_command = qq{cp "%p" "$temp_path"} + . qq{ && mv -f "$temp_path" "$path/%f"}; + } # Enable archive_mode and archive_command on node $self->append_conf( -- That's all, folks. May the source be with you.