Skip to content

Commit a904022

Browse files
committed
Get current timeline from wal dir.
Also add recovery_target = 'immediate' for some case.
1 parent 4ceb771 commit a904022

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

delete.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ do_delete(time_t backup_id)
2727

2828
/* DATE are always required */
2929
if (backup_id == 0)
30-
elog(ERROR, "required delete range option not specified: delete DATE");
30+
elog(ERROR, "required backup ID not specified");
3131

3232
/* Lock backup catalog */
3333
ret = catalog_lock();

expected/option.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ ERROR: invalid backup-mode "bad"
7676

7777
###### COMMAND OPTION TEST-0007 ######
7878
###### delete failure without DATE ######
79-
ERROR: required delete range option not specified: delete DATE
79+
ERROR: required backup ID not specified
8080
1
8181

8282
###### COMMAND OPTION TEST-0008 ######

restore.c

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ typedef struct
2424
} restore_files_args;
2525

2626
static void restore_database(pgBackup *backup);
27-
static void create_recovery_conf(const char *target_time,
27+
static void create_recovery_conf(time_t backup_id,
28+
const char *target_time,
2829
const char *target_xid,
2930
const char *target_inclusive,
3031
TimeLineID target_tli);
@@ -43,6 +44,9 @@ static void search_next_wal(const char *path,
4344
parray *timelines);
4445
static void restore_files(void *arg);
4546

47+
TimeLineID findNewestTimeLine(TimeLineID startTLI);
48+
bool existsTimeLineHistory(TimeLineID probeTLI);
49+
4650

4751
int
4852
do_restore(time_t backup_id,
@@ -57,6 +61,7 @@ do_restore(time_t backup_id,
5761
int ret;
5862
TimeLineID cur_tli;
5963
TimeLineID backup_tli;
64+
TimeLineID newest_tli;
6065
parray *backups;
6166
pgBackup *base_backup = NULL;
6267
parray *files;
@@ -95,13 +100,15 @@ do_restore(time_t backup_id,
95100
elog(ERROR, "cannot process any more.");
96101

97102
cur_tli = get_current_timeline(true);
103+
newest_tli = findNewestTimeLine(1);
98104
backup_tli = get_fullbackup_timeline(backups, rt);
99105

100106
/* determine target timeline */
101107
if (target_tli == 0)
102-
target_tli = cur_tli != 0 ? cur_tli : backup_tli;
108+
target_tli = newest_tli != 1 ? newest_tli : backup_tli;
103109

104-
elog(LOG, "current timeline ID = %u", cur_tli);
110+
elog(LOG, "current instance timeline ID = %u", cur_tli);
111+
elog(LOG, "newest timeline ID for wal dir = %u", newest_tli);
105112
elog(LOG, "latest full backup timeline ID = %u", backup_tli);
106113
elog(LOG, "target timeline ID = %u", target_tli);
107114

@@ -216,7 +223,7 @@ do_restore(time_t backup_id,
216223

217224
/* create recovery.conf */
218225
if (!stream_wal || target_time != NULL || target_xid != NULL)
219-
create_recovery_conf(target_time, target_xid, target_inclusive, target_tli);
226+
create_recovery_conf(backup_id, target_time, target_xid, target_inclusive, target_tli);
220227

221228
/* release catalog lock */
222229
catalog_unlock();
@@ -454,7 +461,8 @@ restore_files(void *arg)
454461
}
455462

456463
static void
457-
create_recovery_conf(const char *target_time,
464+
create_recovery_conf(time_t backup_id,
465+
const char *target_time,
458466
const char *target_xid,
459467
const char *target_inclusive,
460468
TimeLineID target_tli)
@@ -484,8 +492,11 @@ create_recovery_conf(const char *target_time,
484492
fprintf(fp, "recovery_target_time = '%s'\n", target_time);
485493
else if (target_xid)
486494
fprintf(fp, "recovery_target_xid = '%s'\n", target_xid);
487-
/*else
488-
fprintf(fp, "recovery_target = 'immediate'\n");*/
495+
else if (backup_id != 0)
496+
{
497+
fprintf(fp, "recovery_target = 'immediate'\n");
498+
fprintf(fp, "recovery_target_action = 'promote'\n");
499+
}
489500

490501
if (target_inclusive)
491502
fprintf(fp, "recovery_target_inclusive = '%s'\n", target_inclusive);
@@ -797,3 +808,67 @@ checkIfCreateRecoveryConf(const char *target_time,
797808
return rt;
798809

799810
}
811+
812+
813+
/*
814+
* Probe whether a timeline history file exists for the given timeline ID
815+
*/
816+
bool
817+
existsTimeLineHistory(TimeLineID probeTLI)
818+
{
819+
char path[MAXPGPATH];
820+
FILE *fd;
821+
822+
/* Timeline 1 does not have a history file, so no need to check */
823+
if (probeTLI == 1)
824+
return false;
825+
826+
snprintf(path, lengthof(path), "%s/%08X.history", arclog_path, probeTLI);
827+
fd = fopen(path, "r");
828+
if (fd != NULL)
829+
{
830+
fclose(fd);
831+
return true;
832+
}
833+
else
834+
{
835+
if (errno != ENOENT)
836+
elog(ERROR, "Failed directory for path: %s", path);
837+
return false;
838+
}
839+
}
840+
841+
/*
842+
* Find the newest existing timeline, assuming that startTLI exists.
843+
*
844+
* Note: while this is somewhat heuristic, it does positively guarantee
845+
* that (result + 1) is not a known timeline, and therefore it should
846+
* be safe to assign that ID to a new timeline.
847+
*/
848+
TimeLineID
849+
findNewestTimeLine(TimeLineID startTLI)
850+
{
851+
TimeLineID newestTLI;
852+
TimeLineID probeTLI;
853+
854+
/*
855+
* The algorithm is just to probe for the existence of timeline history
856+
* files. XXX is it useful to allow gaps in the sequence?
857+
*/
858+
newestTLI = startTLI;
859+
860+
for (probeTLI = startTLI + 1;; probeTLI++)
861+
{
862+
if (existsTimeLineHistory(probeTLI))
863+
{
864+
newestTLI = probeTLI; /* probeTLI exists */
865+
}
866+
else
867+
{
868+
/* doesn't exist, assume we're done */
869+
break;
870+
}
871+
}
872+
873+
return newestTLI;
874+
}

0 commit comments

Comments
 (0)