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

Commit 6fedb2e

Browse files
author
Artur Zakirov
committed
Check in SHOW command that backups in RUNNING status
1 parent 5181420 commit 6fedb2e

File tree

8 files changed

+119
-22
lines changed

8 files changed

+119
-22
lines changed

backup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ do_backup(bool smooth_checkpoint)
432432
elog(LOG, "----------------------------------------");
433433

434434
/* get exclusive lock of backup catalog */
435-
catalog_lock(true);
435+
catalog_lock(true, NULL);
436436

437437
/* initialize backup result */
438438
current.status = BACKUP_STATUS_RUNNING;

catalog.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ unlink_lock_atexit(void)
4242
/*
4343
* Create a lockfile.
4444
*/
45-
int
46-
catalog_lock(bool check_catalog)
45+
void
46+
catalog_lock(bool check_catalog, pid_t *run_pid)
4747
{
4848
int fd;
4949
char buffer[MAXPGPATH * 2 + 256];
@@ -53,6 +53,9 @@ catalog_lock(bool check_catalog)
5353
pid_t my_pid,
5454
my_p_pid;
5555

56+
if (run_pid)
57+
*run_pid = 0;
58+
5659
join_path_components(lock_file, backup_path, BACKUP_CATALOG_PID);
5760

5861
/*
@@ -149,7 +152,16 @@ catalog_lock(bool check_catalog)
149152
{
150153
if (kill(encoded_pid, 0) == 0 ||
151154
(errno != ESRCH && errno != EPERM))
152-
elog(ERROR, "lock file \"%s\" already exists", lock_file);
155+
{
156+
/* If run_pid was specified just return encoded_pid */
157+
if (run_pid)
158+
{
159+
*run_pid = encoded_pid;
160+
return;
161+
}
162+
else
163+
elog(ERROR, "lock file \"%s\" already exists", lock_file);
164+
}
153165
}
154166

155167
/*
@@ -220,8 +232,6 @@ catalog_lock(bool check_catalog)
220232
elog(ERROR, "Backup directory was initialized for system id = %ld, but target system id = %ld",
221233
system_identifier, id);
222234
}
223-
224-
return 0;
225235
}
226236

227237
/*

delete.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ do_delete(time_t backup_id)
3131
elog(ERROR, "required backup ID not specified");
3232

3333
/* Lock backup catalog */
34-
catalog_lock(false);
34+
catalog_lock(false, NULL);
3535

3636
/* Get complete list of backups */
3737
backup_list = catalog_get_backup_list(0);
@@ -98,7 +98,7 @@ do_deletewal(time_t backup_id, bool strict, bool need_catalog_lock)
9898

9999
/* Lock backup catalog */
100100
if (need_catalog_lock)
101-
catalog_lock(false);
101+
catalog_lock(false, NULL);
102102

103103
/* Find oldest LSN, used by backups */
104104
backup_list = catalog_get_backup_list(0);
@@ -154,7 +154,7 @@ do_retention_purge(void)
154154
elog(ERROR, "retention policy is not set");
155155

156156
/* Lock backup catalog */
157-
catalog_lock(false);
157+
catalog_lock(false, NULL);
158158

159159
/* Get a complete list of backups. */
160160
backup_list = catalog_get_backup_list(0);

pg_probackup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ extern parray *catalog_get_backup_list(time_t backup_id);
300300
extern pgBackup *catalog_get_last_data_backup(parray *backup_list,
301301
TimeLineID tli);
302302

303-
extern int catalog_lock(bool check_catalog);
303+
extern void catalog_lock(bool check_catalog, pid_t *run_pid);
304304

305305
extern void pgBackupWriteConfigSection(FILE *out, pgBackup *backup);
306306
extern void pgBackupWriteResultSection(FILE *out, pgBackup *backup);

restore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ do_restore(time_t backup_id,
106106
elog(LOG, "restore start");
107107

108108
/* get exclusive lock of backup catalog */
109-
catalog_lock(false);
109+
catalog_lock(false, NULL);
110110

111111
/* confirm the PostgreSQL server is not running */
112112
if (is_pg_running())

show.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ do_show(time_t backup_id)
2828
*/
2929
if (backup_id != 0)
3030
{
31-
pgBackup *backup;
31+
pgBackup *backup;
32+
pid_t run_pid;
3233

3334
backup = read_backup(backup_id);
3435
if (backup == NULL)
@@ -40,6 +41,18 @@ do_show(time_t backup_id)
4041
/* This is not error case */
4142
return 0;
4243
}
44+
45+
/* Fix backup status */
46+
if (backup->status == BACKUP_STATUS_RUNNING)
47+
{
48+
catalog_lock(false, &run_pid);
49+
if (run_pid == 0)
50+
{
51+
backup->status = BACKUP_STATUS_ERROR;
52+
pgBackupWriteIni(backup);
53+
}
54+
}
55+
4356
show_backup_detail(stdout, backup);
4457

4558
/* cleanup */
@@ -184,7 +197,8 @@ get_parent_tli(TimeLineID child_tli)
184197
static void
185198
show_backup_list(FILE *out, parray *backup_list)
186199
{
187-
int i;
200+
int i;
201+
pid_t run_pid = -1;
188202

189203
/* show header */
190204
fputs("=========================================================================================\n", out);
@@ -193,14 +207,25 @@ show_backup_list(FILE *out, parray *backup_list)
193207

194208
for (i = 0; i < parray_num(backup_list); i++)
195209
{
196-
pgBackup *backup;
197-
const char *modes[] = { "", "PAGE", "PTRACK", "FULL", "", "PAGE+STREAM", "PTRACK+STREAM", "FULL+STREAM"};
198-
TimeLineID parent_tli;
199-
char timestamp[20] = "----";
200-
char duration[20] = "----";
201-
char data_bytes_str[10] = "----";
202-
203-
backup = parray_get(backup_list, i);
210+
pgBackup *backup = parray_get(backup_list, i);
211+
const char *modes[] = {"", "PAGE", "PTRACK", "FULL", "", "PAGE+STREAM", "PTRACK+STREAM", "FULL+STREAM"};
212+
TimeLineID parent_tli;
213+
char timestamp[20] = "----";
214+
char duration[20] = "----";
215+
char data_bytes_str[10] = "----";
216+
217+
/* Fix backup status */
218+
if (backup->status == BACKUP_STATUS_RUNNING)
219+
{
220+
if (run_pid == -1)
221+
catalog_lock(false, &run_pid);
222+
223+
if (run_pid == 0 || i + 1 < parray_num(backup_list))
224+
backup->status = BACKUP_STATUS_ERROR;
225+
226+
if (run_pid == 0)
227+
pgBackupWriteIni(backup);
228+
}
204229

205230
if (backup->recovery_time != (time_t) 0)
206231
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);

tests/restore_test.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ def test_restore_to_latest_1(self):
3333
node.stop({"-m": "immediate"})
3434
node.cleanup()
3535

36+
# 1 - Test recovery from latest
3637
self.assertIn(six.b("INFO: restore complete"),
3738
self.restore_pb(node, options=["-j", "4", "--verbose"]))
3839

40+
# 2 - Test that recovery.conf was created
41+
recovery_conf = path.join(node.data_dir, "recovery.conf")
42+
self.assertEqual(path.isfile(recovery_conf), True)
43+
3944
node.start({"-t": "600"})
4045

4146
after = node.execute("postgres", "SELECT * FROM pgbench_branches")
@@ -556,3 +561,60 @@ def test_restore_with_tablespace_mapping_12(self):
556561
self.assertEqual(id[0][0], 2)
557562

558563
node.stop()
564+
565+
def test_restore_with_tablespace_mapping_13(self):
566+
"""recovery using tablespace-mapping option and page backup"""
567+
node = self.make_bnode('restore_with_tablespace_mapping_13',
568+
base_dir="tmp_dirs/restore/restore_with_tablespace_mapping_13")
569+
node.start()
570+
self.assertEqual(self.init_pb(node), six.b(""))
571+
572+
# Full backup
573+
self.backup_pb(node)
574+
self.assertEqual(self.show_pb(node)[0].status, six.b("OK"))
575+
576+
# Create tablespace
577+
tblspc_path = path.join(node.base_dir, "tblspc")
578+
os.makedirs(tblspc_path)
579+
with node.connect("postgres") as con:
580+
con.connection.autocommit = True
581+
con.execute("CREATE TABLESPACE tblspc LOCATION '%s'" % tblspc_path)
582+
con.connection.autocommit = False
583+
con.execute("CREATE TABLE tbl AS SELECT * FROM generate_series(0,3) AS integer")
584+
con.commit()
585+
586+
# First page backup
587+
self.backup_pb(node, backup_type="page")
588+
self.assertEqual(self.show_pb(node)[1].status, six.b("OK"))
589+
590+
# Create tablespace table
591+
with node.connect("postgres") as con:
592+
con.connection.autocommit = True
593+
con.execute("CHECKPOINT")
594+
con.connection.autocommit = False
595+
con.execute("CREATE TABLE tbl1 (a int) TABLESPACE tblspc")
596+
con.execute("INSERT INTO tbl1 SELECT * FROM generate_series(0,3) AS integer")
597+
con.commit()
598+
599+
# Second page backup
600+
self.backup_pb(node, backup_type="page")
601+
self.assertEqual(self.show_pb(node)[2].status, six.b("OK"))
602+
603+
node.stop()
604+
node.cleanup()
605+
606+
tblspc_path_new = path.join(node.base_dir, "tblspc_new")
607+
self.assertIn(six.b("INFO: restore complete."),
608+
self.restore_pb(node,
609+
options=["-T", "%s=%s" % (tblspc_path, tblspc_path_new)]))
610+
611+
# Check tables
612+
node.start()
613+
614+
count = node.execute("postgres", "SELECT count(*) FROM tbl")
615+
self.assertEqual(count[0][0], 4)
616+
617+
count = node.execute("postgres", "SELECT count(*) FROM tbl1")
618+
self.assertEqual(count[0][0], 4)
619+
620+
node.stop()

validate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ do_validate(time_t backup_id,
4141
bool success_validate,
4242
need_validate_wal = true;
4343

44-
catalog_lock(false);
44+
catalog_lock(false, NULL);
4545

4646
rt = checkIfCreateRecoveryConf(target_time, target_xid, target_inclusive);
4747
if (rt == NULL)

0 commit comments

Comments
 (0)