Skip to content

Commit a3e5458

Browse files
author
Artur Zakirov
committed
Fix do_validate() and do_restore()
1 parent a997235 commit a3e5458

File tree

7 files changed

+114
-90
lines changed

7 files changed

+114
-90
lines changed

delete.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ pgBackupDeleteFiles(pgBackup *backup)
260260
if (backup->status == BACKUP_STATUS_DELETED)
261261
return 0;
262262

263-
time2iso(timestamp, lengthof(timestamp), backup->start_time);
263+
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);
264264

265265
elog(INFO, "delete: %s %s", base36enc(backup->start_time), timestamp);
266266

doc/pg_probackup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pg_probackup — backup and recovery manager for PostgreSQL.
77
pg_probackup [option...] init
88
pg_probackup [option...] backup
99
pg_probackup [option...] restore [backup_ID]
10-
pg_probackup [option...] validate backup_ID
10+
pg_probackup [option...] validate [backup_ID]
1111
pg_probackup [option...] show [backup_ID]
1212
pg_probackup [option...] delete backup_ID
1313
pg_probackup [option...] delwal [backup_ID]

parsexlog.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ validate_wal(pgBackup *backup,
115115
XLogPageReadPrivate private;
116116
TransactionId last_xid = InvalidTransactionId;
117117
TimestampTz last_time = 0;
118-
char timestamp[100];
118+
char last_timestamp[100],
119+
target_timestamp[100];
119120
bool all_wal = false,
120121
got_endpoint = false;
121122

@@ -125,6 +126,9 @@ validate_wal(pgBackup *backup,
125126
if (xlogreader == NULL)
126127
elog(ERROR, "out of memory");
127128

129+
/* We will check it in the end */
130+
xlogfpath[0] = '\0';
131+
128132
while (true)
129133
{
130134
bool timestamp_record;
@@ -170,19 +174,31 @@ validate_wal(pgBackup *backup,
170174
}
171175

172176
if (last_time > 0)
173-
time2iso(timestamp, lengthof(timestamp), timestamptz_to_time_t(last_time));
177+
time2iso(last_timestamp, lengthof(last_timestamp),
178+
timestamptz_to_time_t(last_time));
174179
else
175-
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);
180+
time2iso(last_timestamp, lengthof(last_timestamp),
181+
backup->recovery_time);
176182
if (last_xid == InvalidTransactionId)
177183
last_xid = backup->recovery_xid;
178184

179185
/* There are all need WAL records */
180186
if (all_wal)
181187
elog(INFO, "Backup validation stopped on %s time and xid:" XID_FMT,
182-
timestamp, last_xid);
188+
last_timestamp, last_xid);
183189
/* There are not need WAL records */
184190
else
185191
{
192+
if (xlogfpath[0] != 0)
193+
{
194+
/* XLOG reader couldnt read WAL segment */
195+
if (xlogreadfd < 0)
196+
elog(WARNING, "WAL segment \"%s\" is absent", xlogfpath);
197+
else
198+
elog(WARNING, "error was occured during reading WAL segment \"%s\"",
199+
xlogfpath);
200+
}
201+
186202
if (!got_endpoint)
187203
elog(ERROR, "there are not enough WAL records to restore from %X/%X to %X/%X",
188204
(uint32) (backup->start_lsn >> 32),
@@ -192,21 +208,21 @@ validate_wal(pgBackup *backup,
192208
else
193209
{
194210
if (target_time > 0)
195-
time2iso(timestamp, lengthof(timestamp),
196-
timestamptz_to_time_t(target_time));
211+
time2iso(target_timestamp, lengthof(target_timestamp),
212+
target_time);
213+
214+
elog(WARNING, "recovery can be done to time %s and xid " XID_FMT,
215+
last_timestamp, last_xid);
197216

198217
if (TransactionIdIsValid(target_xid) && target_time != 0)
199-
elog(WARNING, "there are not WAL records to time %s and xid " XID_FMT,
200-
timestamp, target_xid);
218+
elog(ERROR, "there are not WAL records to time %s and xid " XID_FMT,
219+
target_timestamp, target_xid);
201220
else if (TransactionIdIsValid(target_xid))
202-
elog(WARNING, "there are not WAL records to xid " XID_FMT,
221+
elog(ERROR, "there are not WAL records to xid " XID_FMT,
203222
target_xid);
204223
else if (target_time != 0)
205-
elog(WARNING, "there are not WAL records to time %s ",
206-
timestamp);
207-
208-
elog(WARNING, "recovery can be done to time %s and xid " XID_FMT,
209-
timestamp, last_xid);
224+
elog(ERROR, "there are not WAL records to time %s ",
225+
target_timestamp);
210226
}
211227
}
212228

pg_probackup.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,15 +210,11 @@ main(int argc, char *argv[])
210210
else if (pg_strcasecmp(cmd, "show") == 0)
211211
return do_show(backup_id);
212212
else if (pg_strcasecmp(cmd, "validate") == 0)
213-
{
214-
if (backup_id == 0)
215-
elog(ERROR, "you must specify backup-ID for this command");
216213
return do_validate(backup_id,
217214
target_time,
218215
target_xid,
219216
target_inclusive,
220217
target_tli);
221-
}
222218
else if (pg_strcasecmp(cmd, "delete") == 0)
223219
return do_delete(backup_id);
224220
else if (pg_strcasecmp(cmd, "delwal") == 0)
@@ -247,7 +243,7 @@ pgut_help(bool details)
247243
printf(_(" %s [option...] backup\n"), PROGRAM_NAME);
248244
printf(_(" %s [option...] restore [backup-ID]\n"), PROGRAM_NAME);
249245
printf(_(" %s [option...] show [backup-ID]\n"), PROGRAM_NAME);
250-
printf(_(" %s [option...] validate backup-ID\n"), PROGRAM_NAME);
246+
printf(_(" %s [option...] validate [backup-ID]\n"), PROGRAM_NAME);
251247
printf(_(" %s [option...] delete backup-ID\n"), PROGRAM_NAME);
252248
printf(_(" %s [option...] delwal [backup-ID]\n"), PROGRAM_NAME);
253249
printf(_(" %s [option...] retention show|purge\n"), PROGRAM_NAME);

restore.c

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,18 @@ do_restore(time_t backup_id,
4343
const char *target_inclusive,
4444
TimeLineID target_tli)
4545
{
46-
int i;
47-
int base_index; /* index of base (full) backup */
48-
int ret;
46+
int i;
47+
int base_index; /* index of base (full) backup */
48+
int ret;
4949
TimeLineID cur_tli;
50-
TimeLineID backup_tli;
51-
TimeLineID newest_tli;
52-
parray *backups;
50+
parray *backups;
5351

54-
parray *files;
55-
parray *timelines;
56-
pgBackup *base_backup = NULL;
57-
pgBackup *dest_backup = NULL;
52+
parray *files;
53+
parray *timelines;
54+
pgBackup *base_backup = NULL;
55+
pgBackup *dest_backup = NULL;
5856
pgRecoveryTarget *rt = NULL;
59-
bool backup_id_found = false;
57+
bool backup_id_found = false;
6058

6159
/* PGDATA and ARCLOG_PATH are always required */
6260
if (pgdata == NULL)
@@ -88,21 +86,14 @@ do_restore(time_t backup_id,
8886
elog(ERROR, "cannot process any more.");
8987

9088
cur_tli = get_current_timeline(true);
91-
newest_tli = findNewestTimeLine(1);
92-
backup_tli = get_fullbackup_timeline(backups, rt);
93-
94-
/* determine target timeline */
95-
if (target_tli == 0)
96-
target_tli = newest_tli != 1 ? newest_tli : backup_tli;
97-
9889
elog(LOG, "current instance timeline ID = %u", cur_tli);
99-
elog(LOG, "newest timeline ID for wal dir = %u", newest_tli);
100-
elog(LOG, "latest full backup timeline ID = %u", backup_tli);
101-
elog(LOG, "target timeline ID = %u", target_tli);
102-
10390

104-
/* Read timeline history files from archives */
105-
timelines = readTimeLineHistory(target_tli);
91+
if (target_tli)
92+
{
93+
elog(LOG, "target timeline ID = %u", target_tli);
94+
/* Read timeline history files from archives */
95+
timelines = readTimeLineHistory(target_tli);
96+
}
10697

10798
/* find last full backup which can be used as base backup. */
10899
elog(LOG, "searching recent full backup");
@@ -121,9 +112,9 @@ do_restore(time_t backup_id,
121112
}
122113

123114
if (backup_id == base_backup->start_time &&
124-
base_backup->status != BACKUP_STATUS_OK
125-
)
126-
elog(ERROR, "given backup %s is %s", base36enc(backup_id), status2str(base_backup->status));
115+
base_backup->status != BACKUP_STATUS_OK)
116+
elog(ERROR, "given backup %s is %s", base36enc(backup_id),
117+
status2str(base_backup->status));
127118

128119
if (dest_backup != NULL &&
129120
base_backup->backup_mode == BACKUP_MODE_FULL &&
@@ -137,12 +128,19 @@ do_restore(time_t backup_id,
137128
base_backup->status != BACKUP_STATUS_OK)
138129
continue;
139130

140-
if (satisfy_timeline(timelines, base_backup) &&
141-
satisfy_recovery_target(base_backup, rt) &&
142-
(backup_id_found || backup_id == 0))
143-
goto base_backup_found;
131+
if (target_tli)
132+
{
133+
if (satisfy_timeline(timelines, base_backup) &&
134+
satisfy_recovery_target(base_backup, rt) &&
135+
(backup_id_found || backup_id == 0))
136+
goto base_backup_found;
137+
}
144138
else
145-
backup_id_found = false;
139+
if (satisfy_recovery_target(base_backup, rt) &&
140+
(backup_id_found || backup_id == 0))
141+
goto base_backup_found;
142+
143+
backup_id_found = false;
146144
}
147145
/* no full backup found, cannot restore */
148146
elog(ERROR, "no full backup found, cannot restore.");
@@ -204,9 +202,15 @@ do_restore(time_t backup_id,
204202
continue;
205203

206204
/* is the backup is necessary for restore to target timeline ? */
207-
if (!satisfy_timeline(timelines, backup) ||
208-
!satisfy_recovery_target(backup, rt))
209-
continue;
205+
if (target_tli)
206+
{
207+
if (!satisfy_timeline(timelines, backup) ||
208+
!satisfy_recovery_target(backup, rt))
209+
continue;
210+
}
211+
else
212+
if (!satisfy_recovery_target(backup, rt))
213+
continue;
210214

211215
if (backup_id != 0)
212216
stream_wal = backup->stream;
@@ -217,7 +221,8 @@ do_restore(time_t backup_id,
217221

218222
/* create recovery.conf */
219223
if (!stream_wal || target_time != NULL || target_xid != NULL)
220-
create_recovery_conf(backup_id, target_time, target_xid, target_inclusive, target_tli);
224+
create_recovery_conf(backup_id, target_time, target_xid,
225+
target_inclusive, base_backup->tli);
221226

222227
/* release catalog lock */
223228
catalog_unlock();

tests/expected/option_help.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Usage:
55
pg_probackup [option...] backup
66
pg_probackup [option...] restore [backup-ID]
77
pg_probackup [option...] show [backup-ID]
8-
pg_probackup [option...] validate backup-ID
8+
pg_probackup [option...] validate [backup-ID]
99
pg_probackup [option...] delete backup-ID
1010
pg_probackup [option...] delwal [backup-ID]
1111
pg_probackup [option...] retention show|purge

validate.c

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,16 @@ void do_validate_last(void)
6868
catalog_unlock();
6969
}
7070

71-
int do_validate(time_t backup_id,
72-
const char *target_time,
73-
const char *target_xid,
74-
const char *target_inclusive,
75-
TimeLineID target_tli)
71+
int
72+
do_validate(time_t backup_id,
73+
const char *target_time,
74+
const char *target_xid,
75+
const char *target_inclusive,
76+
TimeLineID target_tli)
7677
{
7778
int i;
7879
int base_index; /* index of base (full) backup */
7980
int last_restored_index; /* index of last restored database backup */
80-
TimeLineID backup_tli;
81-
TimeLineID newest_tli;
8281
parray *timelines;
8382
parray *backups;
8483
pgRecoveryTarget *rt = NULL;
@@ -96,15 +95,9 @@ int do_validate(time_t backup_id,
9695
if (!backups)
9796
elog(ERROR, "cannot process any more.");
9897

99-
newest_tli = findNewestTimeLine(1);
100-
backup_tli = get_fullbackup_timeline(backups, rt);
101-
102-
/* determine target timeline */
103-
if (target_tli == 0)
104-
target_tli = newest_tli != 1 ? newest_tli : backup_tli;
105-
10698
/* Read timeline history files from archives */
107-
timelines = readTimeLineHistory(target_tli);
99+
if (target_tli)
100+
timelines = readTimeLineHistory(target_tli);
108101

109102
/* find last full backup which can be used as base backup. */
110103
elog(LOG, "searching recent full backup");
@@ -116,26 +109,33 @@ int do_validate(time_t backup_id,
116109
continue;
117110

118111
if (backup_id == base_backup->start_time &&
119-
(base_backup->status == BACKUP_STATUS_OK || base_backup->status == BACKUP_STATUS_CORRUPT)
120-
)
112+
(base_backup->status == BACKUP_STATUS_OK ||
113+
base_backup->status == BACKUP_STATUS_CORRUPT))
121114
backup_id_found = true;
122115

123116
if (backup_id == base_backup->start_time &&
124-
(base_backup->status != BACKUP_STATUS_OK && base_backup->status != BACKUP_STATUS_CORRUPT)
125-
)
117+
(base_backup->status != BACKUP_STATUS_OK &&
118+
base_backup->status != BACKUP_STATUS_CORRUPT))
126119
elog(ERROR, "given backup %s is %s", base36enc(backup_id), status2str(base_backup->status));
127120

128121
if (base_backup->backup_mode < BACKUP_MODE_FULL ||
129-
(base_backup->status != BACKUP_STATUS_OK && base_backup->status != BACKUP_STATUS_CORRUPT)
130-
)
122+
(base_backup->status != BACKUP_STATUS_OK &&
123+
base_backup->status != BACKUP_STATUS_CORRUPT))
131124
continue;
132125

133-
if (satisfy_timeline(timelines, base_backup) &&
134-
satisfy_recovery_target(base_backup, rt) &&
135-
(backup_id_found || backup_id == 0))
136-
goto base_backup_found;
126+
if (target_tli)
127+
{
128+
if (satisfy_timeline(timelines, base_backup) &&
129+
satisfy_recovery_target(base_backup, rt) &&
130+
(backup_id_found || backup_id == 0))
131+
goto base_backup_found;
132+
}
137133
else
138-
backup_id_found = false;
134+
if (satisfy_recovery_target(base_backup, rt) &&
135+
(backup_id_found || backup_id == 0))
136+
goto base_backup_found;
137+
138+
backup_id_found = false;
139139
}
140140
/* no full backup found, cannot restore */
141141
elog(ERROR, "no full backup found, cannot validate.");
@@ -159,7 +159,8 @@ int do_validate(time_t backup_id,
159159
pgBackup *backup = (pgBackup *) parray_get(backups, i);
160160

161161
/* don't use incomplete nor different timeline backup */
162-
if ((backup->status != BACKUP_STATUS_OK && backup->status != BACKUP_STATUS_CORRUPT) ||
162+
if ((backup->status != BACKUP_STATUS_OK &&
163+
backup->status != BACKUP_STATUS_CORRUPT) ||
163164
backup->tli != base_backup->tli)
164165
continue;
165166

@@ -175,9 +176,15 @@ int do_validate(time_t backup_id,
175176
continue;
176177

177178
/* is the backup is necessary for restore to target timeline ? */
178-
if (!satisfy_timeline(timelines, backup) ||
179-
!satisfy_recovery_target(backup, rt))
180-
continue;
179+
if (target_tli)
180+
{
181+
if (!satisfy_timeline(timelines, backup) ||
182+
!satisfy_recovery_target(backup, rt))
183+
continue;
184+
}
185+
else
186+
if (!satisfy_recovery_target(backup, rt))
187+
continue;
181188

182189
if (backup_id != 0)
183190
stream_wal = backup->stream;
@@ -187,12 +194,12 @@ int do_validate(time_t backup_id,
187194
}
188195

189196
/* and now we must check WALs */
190-
if (!stream_wal)
197+
if (!stream_wal || rt->time_specified || rt->xid_specified)
191198
validate_wal((pgBackup *) parray_get(backups, last_restored_index),
192199
arclog_path,
193200
rt->recovery_target_time,
194201
rt->recovery_target_xid,
195-
target_tli);
202+
base_backup->tli);
196203

197204
/* release catalog lock */
198205
catalog_unlock();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy