Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aa27178

Browse files
author
Artur Zakirov
committed
Fixes for retention and validate commands
1 parent d10e5f1 commit aa27178

File tree

6 files changed

+95
-41
lines changed

6 files changed

+95
-41
lines changed

catalog.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ pgBackupWriteResultSection(FILE *out, pgBackup *backup)
314314
}
315315
}
316316

317-
/* create backup.ini */
317+
/* create backup.conf */
318318
void
319319
pgBackupWriteIni(pgBackup *backup)
320320
{
@@ -324,7 +324,7 @@ pgBackupWriteIni(pgBackup *backup)
324324
pgBackupGetPath(backup, ini_path, lengthof(ini_path), BACKUP_CONF_FILE);
325325
fp = fopen(ini_path, "wt");
326326
if (fp == NULL)
327-
elog(ERROR, "cannot open INI file \"%s\": %s", ini_path,
327+
elog(ERROR, "cannot open configuration file \"%s\": %s", ini_path,
328328
strerror(errno));
329329

330330
/* configuration section */

delete.c

+19-2
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ do_retention_purge(void)
158158
XLogRecPtr oldest_lsn = InvalidXLogRecPtr;
159159
TimeLineID oldest_tli;
160160
int ret;
161+
bool keep_next_backup = true; /* Do not delete first full backup */
161162

162163
if (retention_redundancy > 0)
163164
elog(LOG, "REDUNDANCY=%u", retention_redundancy);
@@ -190,6 +191,10 @@ do_retention_purge(void)
190191
pgBackup *backup = (pgBackup *) parray_get(backup_list, i);
191192
uint32 backup_num_evaluate = backup_num;
192193

194+
/* Consider only validated and correct backups */
195+
if (backup->status != BACKUP_STATUS_OK)
196+
continue;
197+
193198
/*
194199
* When a validate full backup was found, we can delete the
195200
* backup that is older than it using the number of generations.
@@ -198,12 +203,24 @@ do_retention_purge(void)
198203
backup_num++;
199204

200205
/* Evaluate if this backup is eligible for removal */
201-
if (backup_num_evaluate + 1 <= retention_redundancy ||
202-
(retention_window > 0 && backup->start_time >= days_threshold))
206+
if (keep_next_backup ||
207+
backup_num_evaluate + 1 <= retention_redundancy ||
208+
(retention_window > 0 && backup->recovery_time >= days_threshold))
203209
{
204210
/* Save LSN and Timeline to remove unnecessary WAL segments */
205211
oldest_lsn = backup->start_lsn;
206212
oldest_tli = backup->tli;
213+
214+
/* Save parent backup of this incremental backup */
215+
if (backup->backup_mode != BACKUP_MODE_FULL)
216+
keep_next_backup = true;
217+
/*
218+
* Previous incremental backup was kept or this is first backup
219+
* so do not delete this backup.
220+
*/
221+
else
222+
keep_next_backup = false;
223+
207224
continue;
208225
}
209226

parsexlog.c

+63-22
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,20 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
104104
void
105105
validate_wal(pgBackup *backup,
106106
const char *archivedir,
107-
XLogRecPtr startpoint,
108107
time_t target_time,
109-
TransactionId recovery_target_xid,
108+
TransactionId target_xid,
110109
TimeLineID tli)
111110
{
111+
XLogRecPtr startpoint = backup->start_lsn;
112112
XLogRecord *record;
113113
XLogReaderState *xlogreader;
114114
char *errormsg;
115115
XLogPageReadPrivate private;
116116
TransactionId last_xid = InvalidTransactionId;
117117
TimestampTz last_time = 0;
118-
char timestamp[100];
118+
char timestamp[100];
119+
bool all_wal = false,
120+
got_endpoint = false;
119121

120122
private.archivedir = archivedir;
121123
private.tli = tli;
@@ -130,32 +132,39 @@ validate_wal(pgBackup *backup,
130132
record = XLogReadRecord(xlogreader, startpoint, &errormsg);
131133
if (record == NULL)
132134
{
133-
XLogRecPtr errptr;
134-
135-
errptr = startpoint ? startpoint : xlogreader->EndRecPtr;
136-
if (recovery_target_xid == InvalidTransactionId && target_time == 0)
137-
{
138-
break;
139-
}
140-
141135
if (errormsg)
142-
elog(ERROR, "could not read WAL record at %X/%X: %s",
143-
(uint32) (errptr >> 32), (uint32) (errptr),
144-
errormsg);
145-
else
146-
elog(ERROR, "could not read WAL record at %X/%X",
147-
(uint32) (errptr >> 32),
148-
(uint32) (errptr));
136+
elog(WARNING, "%s", errormsg);
137+
138+
break;
149139
}
150140

141+
/* Got WAL record at stop_lsn */
142+
if (xlogreader->ReadRecPtr == backup->stop_lsn)
143+
got_endpoint = true;
144+
151145
timestamp_record = getRecordTimestamp(xlogreader, &last_time);
152146
if (XLogRecGetXid(xlogreader) != InvalidTransactionId)
153147
last_xid = XLogRecGetXid(xlogreader);
154-
if (recovery_target_xid != InvalidTransactionId && recovery_target_xid == last_xid)
155-
break;
156148

157-
if (target_time != 0 && timestamp_record && timestamptz_to_time_t(last_time) >= target_time)
149+
/* Check target xid */
150+
if (TransactionIdIsValid(target_xid) && target_xid == last_xid)
151+
{
152+
all_wal = true;
153+
break;
154+
}
155+
/* Check target time */
156+
else if (target_time != 0 && timestamp_record && timestamptz_to_time_t(last_time) >= target_time)
157+
{
158+
all_wal = true;
159+
break;
160+
}
161+
/* Stop if there are no target xid and target time */
162+
else if (!TransactionIdIsValid(target_xid) && target_time == 0 &&
163+
xlogreader->ReadRecPtr == backup->stop_lsn)
164+
{
165+
all_wal = true;
158166
break;
167+
}
159168

160169
startpoint = InvalidXLogRecPtr; /* continue reading at next record */
161170
}
@@ -167,7 +176,39 @@ validate_wal(pgBackup *backup,
167176
if (last_xid == InvalidTransactionId)
168177
last_xid = backup->recovery_xid;
169178

170-
elog(INFO, "Backup validation stopped on %s time and xid:" XID_FMT, timestamp, last_xid);
179+
/* There are all need WAL records */
180+
if (all_wal)
181+
elog(INFO, "Backup validation stopped on %s time and xid:" XID_FMT,
182+
timestamp, last_xid);
183+
/* There are not need WAL records */
184+
else
185+
{
186+
if (!got_endpoint)
187+
elog(ERROR, "there are not enough WAL records to restore from %X/%X to %X/%X",
188+
(uint32) (backup->start_lsn >> 32),
189+
(uint32) (backup->start_lsn),
190+
(uint32) (backup->stop_lsn >> 32),
191+
(uint32) (backup->stop_lsn));
192+
else
193+
{
194+
if (target_time > 0)
195+
time2iso(timestamp, lengthof(timestamp),
196+
timestamptz_to_time_t(target_time));
197+
198+
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);
201+
else if (TransactionIdIsValid(target_xid))
202+
elog(WARNING, "there are not WAL records to xid " XID_FMT,
203+
target_xid);
204+
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);
210+
}
211+
}
171212

172213
/* clean */
173214
XLogReaderFree(xlogreader);

pg_probackup.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,8 @@ extern void extractPageMap(const char *datadir,
356356
XLogRecPtr endpoint);
357357
extern void validate_wal(pgBackup *backup,
358358
const char *archivedir,
359-
XLogRecPtr startpoint,
360359
time_t target_time,
361-
TransactionId recovery_target_xid,
360+
TransactionId target_xid,
362361
TimeLineID tli);
363362

364363
/* in util.c */

tests/validate_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@ def test_validate_broke_wal_1(self):
5858

5959
id_backup = self.show_pb(node)[0].id
6060
res = self.validate_pb(node, id_backup, options=['--xid=%s' % target_xid])
61-
self.assertIn(six.b("could not read WAL record at"), res)
61+
self.assertIn(six.b("there are not WAL records to xid"), res)

validate.c

+9-12
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,16 @@ int do_validate(time_t backup_id,
7474
const char *target_inclusive,
7575
TimeLineID target_tli)
7676
{
77-
int i;
78-
int base_index; /* index of base (full) backup */
79-
int last_restored_index; /* index of last restored database backup */
77+
int i;
78+
int base_index; /* index of base (full) backup */
79+
int last_restored_index; /* index of last restored database backup */
8080
TimeLineID backup_tli;
8181
TimeLineID newest_tli;
82-
parray *timelines;
83-
parray *backups;
82+
parray *timelines;
83+
parray *backups;
8484
pgRecoveryTarget *rt = NULL;
85-
pgBackup *base_backup = NULL;
86-
bool backup_id_found = false;
85+
pgBackup *base_backup = NULL;
86+
bool backup_id_found = false;
8787

8888
catalog_lock(false);
8989

@@ -187,15 +187,12 @@ int do_validate(time_t backup_id,
187187
}
188188

189189
/* and now we must check WALs */
190-
{
191-
pgBackup *backup = (pgBackup *) parray_get(backups, last_restored_index);
192-
validate_wal(backup,
190+
if (!stream_wal)
191+
validate_wal((pgBackup *) parray_get(backups, last_restored_index),
193192
arclog_path,
194-
backup->start_lsn,
195193
rt->recovery_target_time,
196194
rt->recovery_target_xid,
197195
target_tli);
198-
}
199196

200197
/* release catalog lock */
201198
catalog_unlock();

0 commit comments

Comments
 (0)