From e82201f5d792c2729b9dda0c113bcd3ae486d850 Mon Sep 17 00:00:00 2001 From: Arthur Zakirov Date: Fri, 29 Mar 2019 16:49:02 +0300 Subject: [PATCH] Consider empty blocks within datafiles. RelationAddExtraBlocks() may extend a relation with empty blocks due to optimisation to avoid contentions. --- src/data.c | 64 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/data.c b/src/data.c index 36e0de28..9cad2eab 100644 --- a/src/data.c +++ b/src/data.c @@ -705,7 +705,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, in = fopen(file->path, PG_BINARY_R); if (in == NULL) { - elog(ERROR, "cannot open backup file \"%s\": %s", file->path, + elog(ERROR, "Cannot open backup file \"%s\": %s", file->path, strerror(errno)); } } @@ -722,7 +722,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, { int errno_tmp = errno; fclose(in); - elog(ERROR, "cannot open restore target file \"%s\": %s", + elog(ERROR, "Cannot open restore target file \"%s\": %s", to_path, strerror(errno_tmp)); } @@ -762,16 +762,22 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, break; /* EOF found */ else if (read_len != 0 && feof(in)) elog(ERROR, - "odd size page found at block %u of \"%s\"", + "Odd size page found at block %u of \"%s\"", blknum, file->path); else - elog(ERROR, "cannot read header of block %u of \"%s\": %s", + elog(ERROR, "Cannot read header of block %u of \"%s\": %s", blknum, file->path, strerror(errno_tmp)); } + if (header.block == 0 && header.compressed_size == 0) + { + elog(VERBOSE, "Skip empty block of \"%s\"", file->path); + continue; + } + if (header.block < blknum) - elog(ERROR, "backup is broken at file->path %s block %u", - file->path, blknum); + elog(ERROR, "Backup is broken at block %u of \"%s\"", + blknum, file->path); blknum = header.block; @@ -792,7 +798,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, read_len = fread(compressed_page.data, 1, MAXALIGN(header.compressed_size), in); if (read_len != MAXALIGN(header.compressed_size)) - elog(ERROR, "cannot read block %u of \"%s\" read %zu of %d", + elog(ERROR, "Cannot read block %u of \"%s\" read %zu of %d", blknum, file->path, read_len, header.compressed_size); /* @@ -816,7 +822,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, blknum, file->path, errormsg); if (uncompressed_size != BLCKSZ) - elog(ERROR, "page of file \"%s\" uncompressed to %d bytes. != BLCKSZ", + elog(ERROR, "Page of file \"%s\" uncompressed to %d bytes. != BLCKSZ", file->path, uncompressed_size); } @@ -827,7 +833,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, * Seek and write the restored page. */ if (fseek(out, write_pos, SEEK_SET) < 0) - elog(ERROR, "cannot seek block %u of \"%s\": %s", + elog(ERROR, "Cannot seek block %u of \"%s\": %s", blknum, to_path, strerror(errno)); if (write_header) @@ -835,7 +841,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, /* We uncompressed the page, so its size is BLCKSZ */ header.compressed_size = BLCKSZ; if (fwrite(&header, 1, sizeof(header), out) != sizeof(header)) - elog(ERROR, "cannot write header of block %u of \"%s\": %s", + elog(ERROR, "Cannot write header of block %u of \"%s\": %s", blknum, file->path, strerror(errno)); } @@ -846,14 +852,14 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, if (uncompressed_size == BLCKSZ) { if (fwrite(page.data, 1, BLCKSZ, out) != BLCKSZ) - elog(ERROR, "cannot write block %u of \"%s\": %s", + elog(ERROR, "Cannot write block %u of \"%s\": %s", blknum, file->path, strerror(errno)); } else { /* */ if (fwrite(compressed_page.data, 1, BLCKSZ, out) != BLCKSZ) - elog(ERROR, "cannot write block %u of \"%s\": %s", + elog(ERROR, "Cannot write block %u of \"%s\": %s", blknum, file->path, strerror(errno)); } } @@ -891,7 +897,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, * Truncate file to this length. */ if (ftruncate(fileno(out), write_pos) != 0) - elog(ERROR, "cannot truncate \"%s\": %s", + elog(ERROR, "Cannot truncate \"%s\": %s", file->path, strerror(errno)); elog(VERBOSE, "Delta truncate file %s to block %u", file->path, truncate_from); @@ -905,14 +911,14 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, if (in) fclose(in); fclose(out); - elog(ERROR, "cannot change mode of \"%s\": %s", to_path, + elog(ERROR, "Cannot change mode of \"%s\": %s", to_path, strerror(errno_tmp)); } if (fflush(out) != 0 || fsync(fileno(out)) != 0 || fclose(out)) - elog(ERROR, "cannot write \"%s\": %s", to_path, strerror(errno)); + elog(ERROR, "Cannot write \"%s\": %s", to_path, strerror(errno)); if (in) fclose(in); } @@ -1571,7 +1577,7 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, pg_crc32 crc; bool use_crc32c = backup_version <= 20021 || backup_version >= 20025; - elog(VERBOSE, "validate relation blocks for file %s", file->path); + elog(VERBOSE, "Validate relation blocks for file %s", file->path); in = fopen(file->path, PG_BINARY_R); if (in == NULL) @@ -1582,7 +1588,7 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, return false; } - elog(ERROR, "cannot open file \"%s\": %s", + elog(ERROR, "Cannot open file \"%s\": %s", file->path, strerror(errno)); } @@ -1606,20 +1612,26 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, break; /* EOF found */ else if (read_len != 0 && feof(in)) elog(WARNING, - "odd size page found at block %u of \"%s\"", + "Odd size page found at block %u of \"%s\"", blknum, file->path); else - elog(WARNING, "cannot read header of block %u of \"%s\": %s", + elog(WARNING, "Cannot read header of block %u of \"%s\": %s", blknum, file->path, strerror(errno_tmp)); return false; } COMP_FILE_CRC32(use_crc32c, crc, &header, read_len); + if (header.block == 0 && header.compressed_size == 0) + { + elog(VERBOSE, "Skip empty block of \"%s\"", file->path); + continue; + } + if (header.block < blknum) { - elog(WARNING, "backup is broken at file->path %s block %u", - file->path, blknum); + elog(WARNING, "Backup is broken at block %u of \"%s\"", + blknum, file->path); return false; } @@ -1627,8 +1639,8 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, if (header.compressed_size == PageIsTruncated) { - elog(LOG, "File %s, block %u is truncated", - file->path, blknum); + elog(LOG, "Block %u of \"%s\" is truncated", + blknum, file->path); continue; } @@ -1638,7 +1650,7 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, MAXALIGN(header.compressed_size), in); if (read_len != MAXALIGN(header.compressed_size)) { - elog(WARNING, "cannot read block %u of \"%s\" read %zu of %d", + elog(WARNING, "Cannot read block %u of \"%s\" read %zu of %d", blknum, file->path, read_len, header.compressed_size); return false; } @@ -1668,7 +1680,7 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, is_valid = false; continue; } - elog(WARNING, "page of file \"%s\" uncompressed to %d bytes. != BLCKSZ", + elog(WARNING, "Page of file \"%s\" uncompressed to %d bytes. != BLCKSZ", file->path, uncompressed_size); return false; } @@ -1690,7 +1702,7 @@ check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version, if (crc != file->crc) { - elog(WARNING, "Invalid CRC of backup file \"%s\" : %X. Expected %X", + elog(WARNING, "Invalid CRC of backup file \"%s\": %X. Expected %X", file->path, file->crc, crc); is_valid = false; }