Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9255205

Browse files
committed
Merge branch 'master' into fix_ptrack_1230
2 parents 389c82f + 3abbc5d commit 9255205

File tree

15 files changed

+1350
-169
lines changed

15 files changed

+1350
-169
lines changed

src/backup.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,23 +1541,18 @@ pg_stop_backup(pgBackup *backup)
15411541
{
15421542
const char *params[1];
15431543
char name[1024];
1544-
char *backup_id;
1545-
1546-
backup_id = base36enc(backup->start_time);
15471544

15481545
if (!from_replica)
15491546
snprintf(name, lengthof(name), "pg_probackup, backup_id %s",
1550-
backup_id);
1547+
base36enc(backup->start_time));
15511548
else
15521549
snprintf(name, lengthof(name), "pg_probackup, backup_id %s. Replica Backup",
1553-
backup_id);
1550+
base36enc(backup->start_time));
15541551
params[0] = name;
15551552

15561553
res = pgut_execute(conn, "SELECT pg_create_restore_point($1)",
15571554
1, params, true);
15581555
PQclear(res);
1559-
1560-
pfree(backup_id);
15611556
}
15621557

15631558
/*
@@ -1845,7 +1840,8 @@ backup_cleanup(bool fatal, void *userdata)
18451840
*/
18461841
if (current.status == BACKUP_STATUS_RUNNING && current.end_time == 0)
18471842
{
1848-
elog(INFO, "Backup %s is running, setting its status to ERROR", base36enc(current.start_time));
1843+
elog(INFO, "Backup %s is running, setting its status to ERROR",
1844+
base36enc(current.start_time));
18491845
current.end_time = time(NULL);
18501846
current.status = BACKUP_STATUS_ERROR;
18511847
pgBackupWriteBackupControlFile(&current);

src/catalog.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,7 @@ pgBackupWriteControl(FILE *out, pgBackup *backup)
436436

437437
/* 'parent_backup' is set if it is incremental backup */
438438
if (backup->parent_backup != 0)
439-
{
440-
char *parent_backup = base36enc(backup->parent_backup);
441-
442-
fprintf(out, "parent-backup-id = '%s'\n", parent_backup);
443-
free(parent_backup);
444-
}
439+
fprintf(out, "parent-backup-id = '%s'\n", base36enc(backup->parent_backup));
445440
}
446441

447442
/* create BACKUP_CONTROL_FILE */
@@ -556,6 +551,8 @@ readBackupControlFile(const char *path)
556551
backup->status = BACKUP_STATUS_DELETED;
557552
else if (strcmp(status, "DONE") == 0)
558553
backup->status = BACKUP_STATUS_DONE;
554+
else if (strcmp(status, "ORPHAN") == 0)
555+
backup->status = BACKUP_STATUS_ORPHAN;
559556
else if (strcmp(status, "CORRUPT") == 0)
560557
backup->status = BACKUP_STATUS_CORRUPT;
561558
else
@@ -667,21 +664,17 @@ void
667664
pgBackupGetPath2(const pgBackup *backup, char *path, size_t len,
668665
const char *subdir1, const char *subdir2)
669666
{
670-
char *datetime;
671-
672-
datetime = base36enc(backup->start_time);
673-
674667
/* If "subdir1" is NULL do not check "subdir2" */
675668
if (!subdir1)
676-
snprintf(path, len, "%s/%s", backup_instance_path, datetime);
669+
snprintf(path, len, "%s/%s", backup_instance_path,
670+
base36enc(backup->start_time));
677671
else if (!subdir2)
678-
snprintf(path, len, "%s/%s/%s", backup_instance_path, datetime, subdir1);
672+
snprintf(path, len, "%s/%s/%s", backup_instance_path,
673+
base36enc(backup->start_time), subdir1);
679674
/* "subdir1" and "subdir2" is not NULL */
680675
else
681676
snprintf(path, len, "%s/%s/%s/%s", backup_instance_path,
682-
datetime, subdir1, subdir2);
683-
684-
free(datetime);
677+
base36enc(backup->start_time), subdir1, subdir2);
685678

686679
make_native_path(path);
687680
}

src/delete.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ static int
224224
pgBackupDeleteFiles(pgBackup *backup)
225225
{
226226
size_t i;
227-
char *backup_id;
228227
char path[MAXPGPATH];
229228
char timestamp[100];
230229
parray *files;
@@ -235,11 +234,9 @@ pgBackupDeleteFiles(pgBackup *backup)
235234
if (backup->status == BACKUP_STATUS_DELETED)
236235
return 0;
237236

238-
backup_id = base36enc(backup->start_time);
239237
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);
240238

241-
elog(INFO, "delete: %s %s", backup_id, timestamp);
242-
free(backup_id);
239+
elog(INFO, "delete: %s %s", base36enc(backup->start_time), timestamp);
243240

244241
/*
245242
* Update STATUS to BACKUP_STATUS_DELETING in preparation for the case which

src/parsexlog.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ validate_backup_wal_from_start_to_stop(pgBackup *backup,
258258
*/
259259
backup->status = BACKUP_STATUS_CORRUPT;
260260
pgBackupWriteBackupControlFile(backup);
261-
elog(ERROR, "there are not enough WAL records to restore from %X/%X to %X/%X",
261+
elog(WARNING, "There are not enough WAL records to consistenly restore "
262+
"backup %s from START LSN: %X/%X to STOP LSN: %X/%X",
263+
base36enc(backup->start_time),
262264
(uint32) (backup->start_lsn >> 32),
263265
(uint32) (backup->start_lsn),
264266
(uint32) (backup->stop_lsn >> 32),
@@ -288,7 +290,7 @@ validate_wal(pgBackup *backup,
288290
TimeLineID tli)
289291
{
290292
XLogRecPtr startpoint = backup->start_lsn;
291-
char *backup_id;
293+
const char *backup_id;
292294
XLogRecord *record;
293295
XLogReaderState *xlogreader;
294296
char *errormsg;
@@ -327,16 +329,19 @@ validate_wal(pgBackup *backup,
327329
else
328330
validate_backup_wal_from_start_to_stop(backup, (char *) archivedir, tli);
329331

330-
free(backup_id);
331-
332+
if (backup->status == BACKUP_STATUS_CORRUPT)
333+
{
334+
elog(WARNING, "Backup %s WAL segments are corrupted", backup_id);
335+
return;
336+
}
332337
/*
333338
* If recovery target is provided check that we can restore backup to a
334-
* recoverty target time or xid.
339+
* recovery target time or xid.
335340
*/
336341
if (!TransactionIdIsValid(target_xid) && target_time == 0)
337342
{
338-
/* Recoverty target is not given so exit */
339-
elog(INFO, "backup validation completed successfully");
343+
/* Recovery target is not given so exit */
344+
elog(INFO, "Backup %s WAL segments are valid", backup_id);
340345
return;
341346
}
342347

src/pg_probackup.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -423,21 +423,17 @@ main(int argc, char *argv[])
423423
return do_init();
424424
case BACKUP:
425425
{
426-
char *backup_id;
427426
const char *backup_mode;
428427
time_t start_time;
429428

430429
start_time = time(NULL);
431-
backup_id = base36enc(start_time);
432430
backup_mode = deparse_backup_mode(current.backup_mode);
433431

434432
elog(INFO, "Backup start, pg_probackup version: %s, backup ID: %s, backup mode: %s, instance: %s, stream: %s, remote: %s",
435-
PROGRAM_VERSION, backup_id, backup_mode, instance_name,
433+
PROGRAM_VERSION, base36enc(start_time), backup_mode, instance_name,
436434
current.stream ? "true" : "false", is_remote_backup ? "true" : "false");
437435
elog_file(INFO, "command: %s", command);
438436

439-
pfree(backup_id);
440-
441437
return do_backup(start_time);
442438
}
443439
case RESTORE:

src/pg_probackup.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ typedef enum BackupStatus
118118
BACKUP_STATUS_DELETING, /* data files are being deleted */
119119
BACKUP_STATUS_DELETED, /* data files have been deleted */
120120
BACKUP_STATUS_DONE, /* completed but not validated yet */
121+
BACKUP_STATUS_ORPHAN, /* backup validity is unknown but at least one parent backup is corrupted */
121122
BACKUP_STATUS_CORRUPT /* files are corrupted, not available */
122123
} BackupStatus;
123124

@@ -463,7 +464,8 @@ extern const char *status2str(BackupStatus status);
463464
extern void remove_trailing_space(char *buf, int comment_mark);
464465
extern void remove_not_digit(char *buf, size_t len, const char *str);
465466
extern uint32 get_data_checksum_version(bool safe);
466-
extern char *base36enc(long unsigned int value);
467+
extern const char *base36enc(long unsigned int value);
468+
extern char *base36enc_dup(long unsigned int value);
467469
extern long unsigned int base36dec(const char *text);
468470
extern uint64 get_system_identifier(char *pgdata);
469471
extern uint64 get_remote_system_identifier(PGconn *conn);

src/restore.c

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ do_restore_or_validate(time_t target_backup_id,
9090
pgBackup *current_backup = NULL;
9191
pgBackup *dest_backup = NULL;
9292
pgBackup *base_full_backup = NULL;
93+
pgBackup *corrupted_backup = NULL;
9394
int dest_backup_index = 0;
9495
int base_full_backup_index = 0;
96+
int corrupted_backup_index = 0;
9597
char *action = is_restore ? "Restore":"Validate";
9698

9799
if (is_restore)
@@ -193,8 +195,8 @@ do_restore_or_validate(time_t target_backup_id,
193195
{
194196
if (current_backup->status != BACKUP_STATUS_OK)
195197
elog(ERROR, "base backup %s for given backup %s is in %s status",
196-
base36enc(current_backup->start_time),
197-
base36enc(dest_backup->start_time),
198+
base36enc_dup(current_backup->start_time),
199+
base36enc_dup(dest_backup->start_time),
198200
status2str(current_backup->status));
199201
else
200202
{
@@ -205,7 +207,7 @@ do_restore_or_validate(time_t target_backup_id,
205207
}
206208
}
207209
else
208-
/* Skip differential backups are ok */
210+
/* It`s ok to skip incremental backup */
209211
continue;
210212
}
211213
}
@@ -220,36 +222,87 @@ do_restore_or_validate(time_t target_backup_id,
220222
if (is_restore)
221223
check_tablespace_mapping(dest_backup);
222224

225+
if (dest_backup->backup_mode != BACKUP_MODE_FULL)
226+
elog(INFO, "Validating parents for backup %s", base36enc(dest_backup->start_time));
227+
223228
/*
224229
* Validate backups from base_full_backup to dest_backup.
225230
*/
226231
for (i = base_full_backup_index; i >= dest_backup_index; i--)
227232
{
228233
pgBackup *backup = (pgBackup *) parray_get(backups, i);
229234
pgBackupValidate(backup);
235+
if (backup->status == BACKUP_STATUS_CORRUPT)
236+
{
237+
corrupted_backup = backup;
238+
corrupted_backup_index = i;
239+
break;
240+
}
241+
}
242+
/* There is no point in wal validation
243+
* if there is corrupted backup between base_backup and dest_backup
244+
*/
245+
if (!corrupted_backup)
246+
/*
247+
* Validate corresponding WAL files.
248+
* We pass base_full_backup timeline as last argument to this function,
249+
* because it's needed to form the name of xlog file.
250+
*/
251+
validate_wal(dest_backup, arclog_path, rt->recovery_target_time,
252+
rt->recovery_target_xid, base_full_backup->tli);
253+
254+
/* Set every incremental backup between corrupted backup and nearest FULL backup as orphans */
255+
if (corrupted_backup)
256+
{
257+
for (i = corrupted_backup_index - 1; i >= 0; i--)
258+
{
259+
pgBackup *backup = (pgBackup *) parray_get(backups, i);
260+
/* Mark incremental OK backup as orphan */
261+
if (backup->backup_mode == BACKUP_MODE_FULL)
262+
break;
263+
if (backup->status != BACKUP_STATUS_OK)
264+
continue;
265+
else
266+
{
267+
char *backup_id,
268+
*corrupted_backup_id;
269+
270+
backup->status = BACKUP_STATUS_ORPHAN;
271+
pgBackupWriteBackupControlFile(backup);
272+
273+
backup_id = base36enc_dup(backup->start_time);
274+
corrupted_backup_id = base36enc_dup(corrupted_backup->start_time);
275+
276+
elog(WARNING, "Backup %s is orphaned because his parent %s is corrupted",
277+
backup_id, corrupted_backup_id);
278+
279+
free(backup_id);
280+
free(corrupted_backup_id);
281+
}
282+
}
230283
}
231284

232285
/*
233-
* Validate corresponding WAL files.
234-
* We pass base_full_backup timeline as last argument to this function,
235-
* because it's needed to form the name of xlog file.
286+
* If dest backup is corrupted or was orphaned in previous check
287+
* produce corresponding error message
236288
*/
237-
validate_wal(dest_backup, arclog_path, rt->recovery_target_time,
238-
rt->recovery_target_xid, base_full_backup->tli);
239-
289+
if (dest_backup->status == BACKUP_STATUS_OK)
290+
elog(INFO, "Backup %s is valid.", base36enc(dest_backup->start_time));
291+
else if (dest_backup->status == BACKUP_STATUS_CORRUPT)
292+
elog(ERROR, "Backup %s is corrupt.", base36enc(dest_backup->start_time));
293+
else if (dest_backup->status == BACKUP_STATUS_ORPHAN)
294+
elog(ERROR, "Backup %s is orphan.", base36enc(dest_backup->start_time));
295+
else
296+
elog(ERROR, "Backup %s has status: %s",
297+
base36enc(dest_backup->start_time), status2str(dest_backup->status));
240298

241299
/* We ensured that all backups are valid, now restore if required */
242300
if (is_restore)
243301
{
244-
pgBackup *backup;
245302
for (i = base_full_backup_index; i >= dest_backup_index; i--)
246303
{
247-
backup = (pgBackup *) parray_get(backups, i);
248-
if (backup->status == BACKUP_STATUS_OK)
249-
restore_backup(backup);
250-
else
251-
elog(ERROR, "backup %s is not valid",
252-
base36enc(backup->start_time));
304+
pgBackup *backup = (pgBackup *) parray_get(backups, i);
305+
restore_backup(backup);
253306
}
254307

255308
/*
@@ -366,13 +419,7 @@ restore_backup(pgBackup *backup)
366419
parray_free(files);
367420

368421
if (LOG_LEVEL_CONSOLE <= LOG || LOG_LEVEL_FILE <= LOG)
369-
{
370-
char *backup_id;
371-
372-
backup_id = base36enc(backup->start_time);
373-
elog(LOG, "restore %s backup completed", backup_id);
374-
free(backup_id);
375-
}
422+
elog(LOG, "restore %s backup completed", base36enc(backup->start_time));
376423
}
377424

378425
/*
@@ -592,13 +639,8 @@ check_tablespace_mapping(pgBackup *backup)
592639
read_tablespace_map(links, this_backup_path);
593640

594641
if (LOG_LEVEL_CONSOLE <= LOG || LOG_LEVEL_FILE <= LOG)
595-
{
596-
char *backup_id;
597-
598-
backup_id = base36enc(backup->start_time);
599-
elog(LOG, "check tablespace directories of backup %s", backup_id);
600-
pfree(backup_id);
601-
}
642+
elog(LOG, "check tablespace directories of backup %s",
643+
base36enc(backup->start_time));
602644

603645
/* 1 - each OLDDIR must have an entry in tablespace_map file (links) */
604646
for (cell = tablespace_dirs.head; cell; cell = cell->next)

src/show.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ show_backup_list(FILE *out, parray *backup_list)
234234
{
235235
pgBackup *backup = parray_get(backup_list, i);
236236
TimeLineID parent_tli;
237-
char *backup_id;
238237
char timestamp[100] = "----";
239238
char duration[20] = "----";
240239
char data_bytes_str[10] = "----";
@@ -255,12 +254,11 @@ show_backup_list(FILE *out, parray *backup_list)
255254

256255
/* Get parent timeline before printing */
257256
parent_tli = get_parent_tli(backup->tli);
258-
backup_id = base36enc(backup->start_time);
259257

260258
fprintf(out, " %-11s %-8s %-6s %-22s %-6s %-7s %3d / %-3d %5s %6s %2X/%-8X %2X/%-8X %-8s\n",
261259
instance_name,
262260
(backup->server_version[0] ? backup->server_version : "----"),
263-
backup_id,
261+
base36enc(backup->start_time),
264262
timestamp,
265263
pgBackupGetBackupMode(backup),
266264
backup->stream ? "STREAM": "ARCHIVE",
@@ -273,8 +271,6 @@ show_backup_list(FILE *out, parray *backup_list)
273271
(uint32) (backup->stop_lsn >> 32),
274272
(uint32) backup->stop_lsn,
275273
status2str(backup->status));
276-
277-
free(backup_id);
278274
}
279275
}
280276

0 commit comments

Comments
 (0)