diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 9f735a2c07..48bacfe5dd 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -1258,6 +1258,7 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf int i; pgoff_t len = 0; char page[BLCKSZ]; + int block_error = -1; size_t pad; PageHeader phdr; int segmentno = 0; @@ -1328,9 +1329,16 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf verify_checksum = false; continue; } - for (i = 0; i < cnt / BLCKSZ; i++) + + /* + * Validate all blocks in the buffer. If checking after the buffer + * was reread then start at the block that caused the reread. + */ + for (i = block_error == -1 ? 0 : block_error; i < cnt / BLCKSZ; i++) { + blkno = len / BLCKSZ + i; memcpy(page, (buf + BLCKSZ * i), BLCKSZ); + /* * Only check pages which have not been modified since the * start of the base backup. @@ -1341,6 +1349,18 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf phdr = (PageHeader) page; if (phdr->pd_checksum != checksum) { + /* + * If first time encountering an error on this block + * then read the last buffer again to see if the + * checksum is corrected. + */ + if (block_error == -1) + { + block_error = i; + fseek(fp, -cnt, SEEK_CUR); + break; + } + ereport(WARNING, (errmsg("checksum verification failed in file " "\"%s\", block %d: calculated %X but " @@ -1350,8 +1370,12 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf checksum_failure = true; } } - blkno++; + block_error = -1; } + + /* Read the buffer again if there were checksum errors */ + if (block_error != -1) + continue; } /* Send the chunk as a CopyData message */