Skip to content

Commit b4e707b

Browse files
committed
Merge branch 'master' into pgpro-2071
2 parents 0e5cc88 + 59da24d commit b4e707b

14 files changed

+162
-205
lines changed

Diff for: src/backup.c

+13-12
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#include "utils/thread.h"
2525
#include <time.h>
2626

27-
#define PG_STOP_BACKUP_TIMEOUT 300
28-
2927
/*
3028
* Macro needed to parse ptrack.
3129
* NOTE Keep those values syncronised with definitions in ptrack.h
@@ -310,7 +308,7 @@ remote_copy_file(PGconn *conn, pgFile* file)
310308
to_path, strerror(errno_tmp));
311309
}
312310

313-
INIT_TRADITIONAL_CRC32(file->crc);
311+
INIT_FILE_CRC32(true, file->crc);
314312

315313
/* read from stream and write to backup file */
316314
while (1)
@@ -336,14 +334,14 @@ remote_copy_file(PGconn *conn, pgFile* file)
336334
{
337335
write_buffer_size = Min(row_length, sizeof(buf));
338336
memcpy(buf, copybuf, write_buffer_size);
339-
COMP_TRADITIONAL_CRC32(file->crc, buf, write_buffer_size);
337+
COMP_FILE_CRC32(true, file->crc, buf, write_buffer_size);
340338

341339
/* TODO calc checksum*/
342340
if (fwrite(buf, 1, write_buffer_size, out) != write_buffer_size)
343341
{
344342
errno_tmp = errno;
345343
/* oops */
346-
FIN_TRADITIONAL_CRC32(file->crc);
344+
FIN_FILE_CRC32(true, file->crc);
347345
fclose(out);
348346
PQfinish(conn);
349347
elog(ERROR, "cannot write to \"%s\": %s", to_path,
@@ -367,7 +365,7 @@ remote_copy_file(PGconn *conn, pgFile* file)
367365
}
368366

369367
file->write_size = (int64) file->read_size;
370-
FIN_TRADITIONAL_CRC32(file->crc);
368+
FIN_FILE_CRC32(true, file->crc);
371369

372370
fclose(out);
373371
}
@@ -1883,8 +1881,8 @@ pg_stop_backup(pgBackup *backup)
18831881
}
18841882

18851883
/*
1886-
* Wait for the result of pg_stop_backup(),
1887-
* but no longer than PG_STOP_BACKUP_TIMEOUT seconds
1884+
* Wait for the result of pg_stop_backup(), but no longer than
1885+
* archive_timeout seconds
18881886
*/
18891887
if (pg_stop_backup_is_sent && !in_cleanup)
18901888
{
@@ -1907,14 +1905,14 @@ pg_stop_backup(pgBackup *backup)
19071905
elog(INFO, "wait for pg_stop_backup()");
19081906

19091907
/*
1910-
* If postgres haven't answered in PG_STOP_BACKUP_TIMEOUT seconds,
1908+
* If postgres haven't answered in archive_timeout seconds,
19111909
* send an interrupt.
19121910
*/
1913-
if (pg_stop_backup_timeout > PG_STOP_BACKUP_TIMEOUT)
1911+
if (pg_stop_backup_timeout > instance_config.archive_timeout)
19141912
{
19151913
pgut_cancel(conn);
19161914
elog(ERROR, "pg_stop_backup doesn't answer in %d seconds, cancel it",
1917-
PG_STOP_BACKUP_TIMEOUT);
1915+
instance_config.archive_timeout);
19181916
}
19191917
}
19201918
else
@@ -2290,9 +2288,12 @@ backup_files(void *arg)
22902288
continue;
22912289
}
22922290
}
2291+
else if (strcmp(file->name, "pg_control") == 0)
2292+
copy_pgcontrol_file(arguments->from_root, arguments->to_root,
2293+
file);
22932294
else
22942295
{
2295-
bool skip = false;
2296+
bool skip = false;
22962297

22972298
/* If non-data file has not changed since last backup... */
22982299
if (prev_file && file->exists_in_prev &&

Diff for: src/data.c

+13-13
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ compress_and_backup_page(pgFile *file, BlockNumber blknum,
487487
blknum, header.compressed_size, write_buffer_size); */
488488

489489
/* Update CRC */
490-
COMP_TRADITIONAL_CRC32(*crc, write_buffer, write_buffer_size);
490+
COMP_FILE_CRC32(true, *crc, write_buffer, write_buffer_size);
491491

492492
/* write data page */
493493
if(fwrite(write_buffer, 1, write_buffer_size, out) != write_buffer_size)
@@ -547,13 +547,13 @@ backup_data_file(backup_files_arg* arguments,
547547
/* reset size summary */
548548
file->read_size = 0;
549549
file->write_size = 0;
550-
INIT_TRADITIONAL_CRC32(file->crc);
550+
INIT_FILE_CRC32(true, file->crc);
551551

552552
/* open backup mode file for read */
553553
in = fopen(file->path, PG_BINARY_R);
554554
if (in == NULL)
555555
{
556-
FIN_TRADITIONAL_CRC32(file->crc);
556+
FIN_FILE_CRC32(true, file->crc);
557557

558558
/*
559559
* If file is not found, this is not en error.
@@ -658,7 +658,7 @@ backup_data_file(backup_files_arg* arguments,
658658
to_path, strerror(errno));
659659
fclose(in);
660660

661-
FIN_TRADITIONAL_CRC32(file->crc);
661+
FIN_FILE_CRC32(true, file->crc);
662662

663663
/*
664664
* If we have pagemap then file in the backup can't be a zero size.
@@ -927,7 +927,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
927927
struct stat st;
928928
pg_crc32 crc;
929929

930-
INIT_TRADITIONAL_CRC32(crc);
930+
INIT_FILE_CRC32(true, crc);
931931

932932
/* reset size summary */
933933
file->read_size = 0;
@@ -937,7 +937,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
937937
in = fopen(file->path, PG_BINARY_R);
938938
if (in == NULL)
939939
{
940-
FIN_TRADITIONAL_CRC32(crc);
940+
FIN_FILE_CRC32(true, crc);
941941
file->crc = crc;
942942

943943
/* maybe deleted, it's not error */
@@ -986,7 +986,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
986986
strerror(errno_tmp));
987987
}
988988
/* update CRC */
989-
COMP_TRADITIONAL_CRC32(crc, buf, read_len);
989+
COMP_FILE_CRC32(true, crc, buf, read_len);
990990

991991
file->read_size += read_len;
992992
}
@@ -1013,14 +1013,14 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
10131013
strerror(errno_tmp));
10141014
}
10151015
/* update CRC */
1016-
COMP_TRADITIONAL_CRC32(crc, buf, read_len);
1016+
COMP_FILE_CRC32(true, crc, buf, read_len);
10171017

10181018
file->read_size += read_len;
10191019
}
10201020

10211021
file->write_size = (int64) file->read_size;
10221022
/* finish CRC calculation and store into pgFile */
1023-
FIN_TRADITIONAL_CRC32(crc);
1023+
FIN_FILE_CRC32(true, crc);
10241024
file->crc = crc;
10251025

10261026
/* update file permission */
@@ -1424,7 +1424,7 @@ calc_file_checksum(pgFile *file)
14241424
{
14251425
Assert(S_ISREG(file->mode));
14261426

1427-
file->crc = pgFileGetCRC(file->path, false, false, &file->read_size);
1427+
file->crc = pgFileGetCRC(file->path, true, false, &file->read_size);
14281428
file->write_size = file->read_size;
14291429
}
14301430

@@ -1547,14 +1547,14 @@ validate_one_page(Page page, pgFile *file,
15471547

15481548
/* Valiate pages of datafile in backup one by one */
15491549
bool
1550-
check_file_pages(pgFile *file, XLogRecPtr stop_lsn,
1551-
uint32 checksum_version, uint32 backup_version)
1550+
check_file_pages(pgFile *file, XLogRecPtr stop_lsn, uint32 checksum_version,
1551+
uint32 backup_version)
15521552
{
15531553
size_t read_len = 0;
15541554
bool is_valid = true;
15551555
FILE *in;
15561556
pg_crc32 crc;
1557-
bool use_crc32c = (backup_version <= 20021);
1557+
bool use_crc32c = backup_version <= 20021 || backup_version >= 20025;
15581558

15591559
elog(VERBOSE, "validate relation blocks for file %s", file->name);
15601560

Diff for: src/merge.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -524,9 +524,11 @@ merge_files(void *arg)
524524
* do that.
525525
*/
526526
file->write_size = pgFileSize(to_path_tmp);
527-
file->crc = pgFileGetCRC(to_path_tmp, false, true, NULL);
527+
file->crc = pgFileGetCRC(to_path_tmp, true, true, NULL);
528528
}
529529
}
530+
else if (strcmp(file->name, "pg_control") == 0)
531+
copy_pgcontrol_file(argument->from_root, argument->to_root, file);
530532
else
531533
copy_file(argument->from_root, argument->to_root, file);
532534

Diff for: src/pg_probackup.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "utils/thread.h"
2020
#include <time.h>
2121

22-
const char *PROGRAM_VERSION = "2.0.24";
22+
const char *PROGRAM_VERSION = "2.0.25";
2323
const char *PROGRAM_URL = "https://github.com/postgrespro/pg_probackup";
2424
const char *PROGRAM_EMAIL = "https://github.com/postgrespro/pg_probackup/issues";
2525

Diff for: src/pg_probackup.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ do { \
9696
FIN_TRADITIONAL_CRC32(crc); \
9797
} while (0)
9898

99+
99100
/* Information about single file (or dir) in backup */
100101
typedef struct pgFile
101102
{
@@ -539,8 +540,7 @@ extern void get_wal_file(const char *from_path, const char *to_path);
539540

540541
extern void calc_file_checksum(pgFile *file);
541542

542-
extern bool check_file_pages(pgFile* file,
543-
XLogRecPtr stop_lsn,
543+
extern bool check_file_pages(pgFile *file, XLogRecPtr stop_lsn,
544544
uint32 checksum_version, uint32 backup_version);
545545
/* parsexlog.c */
546546
extern void extractPageMap(const char *archivedir,
@@ -567,11 +567,15 @@ extern XLogRecPtr get_last_wal_lsn(const char *archivedir, XLogRecPtr start_lsn,
567567
/* in util.c */
568568
extern TimeLineID get_current_timeline(bool safe);
569569
extern XLogRecPtr get_checkpoint_location(PGconn *conn);
570-
extern uint64 get_system_identifier(char *pgdata);
570+
extern uint64 get_system_identifier(const char *pgdata_path);
571571
extern uint64 get_remote_system_identifier(PGconn *conn);
572572
extern uint32 get_data_checksum_version(bool safe);
573+
extern pg_crc32c get_pgcontrol_checksum(const char *pgdata_path);
573574
extern uint32 get_xlog_seg_size(char *pgdata_path);
574-
extern void set_min_recovery_point(pgFile *file, const char *backup_path, XLogRecPtr stop_backup_lsn);
575+
extern void set_min_recovery_point(pgFile *file, const char *backup_path,
576+
XLogRecPtr stop_backup_lsn);
577+
extern void copy_pgcontrol_file(const char *from_root, const char *to_root,
578+
pgFile *file);
575579

576580
extern void sanityChecks(void);
577581
extern void time2iso(char *buf, size_t len, time_t time);

Diff for: src/restore.c

+2
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ restore_files(void *arg)
632632
false,
633633
parse_program_version(arguments->backup->program_version));
634634
}
635+
else if (strcmp(file->name, "pg_control") == 0)
636+
copy_pgcontrol_file(from_root, instance_config.pgdata, file);
635637
else
636638
copy_file(from_root, instance_config.pgdata, file);
637639

Diff for: src/show.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ show_instance_plain(parray *backup_list, bool show_name)
363363
time2iso(row->recovery_time, lengthof(row->recovery_time),
364364
backup->recovery_time);
365365
else
366-
StrNCpy(row->recovery_time, "----", 4);
366+
StrNCpy(row->recovery_time, "----", sizeof(row->recovery_time));
367367
widths[cur] = Max(widths[cur], strlen(row->recovery_time));
368368
cur++;
369369

@@ -388,7 +388,7 @@ show_instance_plain(parray *backup_list, bool show_name)
388388
snprintf(row->duration, lengthof(row->duration), "%.*lfs", 0,
389389
difftime(backup->end_time, backup->start_time));
390390
else
391-
StrNCpy(row->duration, "----", 4);
391+
StrNCpy(row->duration, "----", sizeof(row->duration));
392392
widths[cur] = Max(widths[cur], strlen(row->duration));
393393
cur++;
394394

Diff for: src/util.c

+49-8
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ get_checkpoint_location(PGconn *conn)
207207
}
208208

209209
uint64
210-
get_system_identifier(char *pgdata_path)
210+
get_system_identifier(const char *pgdata_path)
211211
{
212212
ControlFileData ControlFile;
213213
char *buffer;
@@ -295,7 +295,27 @@ get_data_checksum_version(bool safe)
295295
return ControlFile.data_checksum_version;
296296
}
297297

298-
/* MinRecoveryPoint 'as-is' is not to be trusted */
298+
pg_crc32c
299+
get_pgcontrol_checksum(const char *pgdata_path)
300+
{
301+
ControlFileData ControlFile;
302+
char *buffer;
303+
size_t size;
304+
305+
/* First fetch file... */
306+
buffer = slurpFile(pgdata_path, "global/pg_control", &size, false);
307+
if (buffer == NULL)
308+
return 0;
309+
digestControlFile(&ControlFile, buffer, size);
310+
pg_free(buffer);
311+
312+
return ControlFile.crc;
313+
}
314+
315+
/*
316+
* Rewrite minRecoveryPoint of pg_control in backup directory. minRecoveryPoint
317+
* 'as-is' is not to be trusted.
318+
*/
299319
void
300320
set_min_recovery_point(pgFile *file, const char *backup_path,
301321
XLogRecPtr stop_backup_lsn)
@@ -324,20 +344,41 @@ set_min_recovery_point(pgFile *file, const char *backup_path,
324344

325345
/* Update checksum in pg_control header */
326346
INIT_CRC32C(ControlFile.crc);
327-
COMP_CRC32C(ControlFile.crc,
328-
(char *) &ControlFile,
347+
COMP_CRC32C(ControlFile.crc, (char *) &ControlFile,
329348
offsetof(ControlFileData, crc));
330349
FIN_CRC32C(ControlFile.crc);
331350

332-
/* paranoia */
333-
checkControlFile(&ControlFile);
334-
335351
/* overwrite pg_control */
336352
snprintf(fullpath, sizeof(fullpath), "%s/%s", backup_path, XLOG_CONTROL_FILE);
337353
writeControlFile(&ControlFile, fullpath);
338354

339355
/* Update pg_control checksum in backup_list */
340-
file->crc = pgFileGetCRC(fullpath, false, true, NULL);
356+
file->crc = ControlFile.crc;
357+
358+
pg_free(buffer);
359+
}
360+
361+
/*
362+
* Copy pg_control file to backup. We do not apply compression to this file.
363+
*/
364+
void
365+
copy_pgcontrol_file(const char *from_root, const char *to_root, pgFile *file)
366+
{
367+
ControlFileData ControlFile;
368+
char *buffer;
369+
size_t size;
370+
char to_path[MAXPGPATH];
371+
372+
buffer = slurpFile(from_root, XLOG_CONTROL_FILE, &size, false);
373+
374+
digestControlFile(&ControlFile, buffer, size);
375+
376+
file->crc = ControlFile.crc;
377+
file->read_size = size;
378+
file->write_size = size;
379+
380+
join_path_components(to_path, to_root, file->path + strlen(from_root) + 1);
381+
writeControlFile(&ControlFile, to_path);
341382

342383
pg_free(buffer);
343384
}

Diff for: src/validate.c

+12-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static bool corrupted_backup_found = false;
2222

2323
typedef struct
2424
{
25+
const char *base_path;
2526
parray *files;
2627
bool corrupted;
2728
XLogRecPtr stop_lsn;
@@ -101,6 +102,7 @@ pgBackupValidate(pgBackup *backup)
101102
{
102103
validate_files_arg *arg = &(threads_args[i]);
103104

105+
arg->base_path = base_path;
104106
arg->files = files;
105107
arg->corrupted = false;
106108
arg->stop_lsn = backup->stop_lsn;
@@ -223,9 +225,17 @@ pgBackupValidateFiles(void *arg)
223225
* CRC-32C algorithm.
224226
* To avoid this problem we need to use different algorithm, CRC-32 in
225227
* this case.
228+
*
229+
* Starting from 2.0.25 we calculate crc of pg_control differently.
226230
*/
227-
crc = pgFileGetCRC(file->path, arguments->backup_version <= 20021,
228-
true, NULL);
231+
if (arguments->backup_version >= 20025 &&
232+
strcmp(file->name, "pg_control") == 0)
233+
crc = get_pgcontrol_checksum(arguments->base_path);
234+
else
235+
crc = pgFileGetCRC(file->path,
236+
arguments->backup_version <= 20021 ||
237+
arguments->backup_version >= 20025,
238+
true, NULL);
229239
if (crc != file->crc)
230240
{
231241
elog(WARNING, "Invalid CRC of backup file \"%s\" : %X. Expected %X",

0 commit comments

Comments
 (0)