Use pg_pwrite_zeros() in walmethods.c
authorMichael Paquier <michael@paquier.xyz>
Tue, 8 Nov 2022 03:37:11 +0000 (12:37 +0900)
committerMichael Paquier <michael@paquier.xyz>
Tue, 8 Nov 2022 03:37:11 +0000 (12:37 +0900)
This change impacts pg_receivewal and pg_basebackup, for the pre-padding
with zeros of all the new non-compressed WAL segments, so as the code is
more robust on partial writes.  This makes the code consistent with the
backend (XLogFileInitInternal) when wal_init_zeros is enabled for the
WAL segment initialization.

Author: Bharath Rupireddy
Reviewed-by: Nathan Bossart, Andres Freund, Thomas Munro, Michael
Paquier
Discussion: https://postgr.es/m/CALj2ACUq7nAb7=bJNbK3yYmp-SZhJcXFR_pLk8un6XgDzDF3OA@mail.gmail.com

src/bin/pg_basebackup/walmethods.c

index bc2e83d02befa6d8c689fab27b30fee638a6e44c..3b06ef6269a0500ea083009a132214aa76efa962 100644 (file)
@@ -220,22 +220,21 @@ dir_open_for_write(WalWriteMethod *wwmethod, const char *pathname,
        /* Do pre-padding on non-compressed files */
        if (pad_to_size && wwmethod->compression_algorithm == PG_COMPRESSION_NONE)
        {
-               PGAlignedXLogBlock zerobuf;
-               int                     bytes;
+               ssize_t         rc;
 
-               memset(zerobuf.data, 0, XLOG_BLCKSZ);
-               for (bytes = 0; bytes < pad_to_size; bytes += XLOG_BLCKSZ)
+               rc = pg_pwrite_zeros(fd, pad_to_size);
+
+               if (rc < 0)
                {
-                       errno = 0;
-                       if (write(fd, zerobuf.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
-                       {
-                               /* If write didn't set errno, assume problem is no disk space */
-                               wwmethod->lasterrno = errno ? errno : ENOSPC;
-                               close(fd);
-                               return NULL;
-                       }
+                       wwmethod->lasterrno = errno;
+                       close(fd);
+                       return NULL;
                }
 
+               /*
+                * pg_pwrite() (called via pg_pwrite_zeros()) may have moved the file
+                * position, so reset it (see win32pwrite.c).
+                */
                if (lseek(fd, 0, SEEK_SET) != 0)
                {
                        wwmethod->lasterrno = errno;