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

Skip to content

Commit 53abc0b

Browse files
author
Daniel Shelepanov
committed
[PGPRO-6938] pg_probackup has been ported to version 15
Has been tested on 15beta2 and 16 tags: pg_probackup
1 parent 223d629 commit 53abc0b

File tree

13 files changed

+379
-95
lines changed

13 files changed

+379
-95
lines changed

src/backup.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,20 +1056,14 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup,
10561056
uint32 lsn_lo;
10571057
params[0] = label;
10581058

1059-
elog(INFO, "wait for pg_start_backup()");
1059+
elog(INFO, "wait for pg_backup_start()");
10601060

10611061
/* 2nd argument is 'fast'*/
10621062
params[1] = smooth ? "false" : "true";
1063-
if (!exclusive_backup)
1064-
res = pgut_execute(conn,
1065-
"SELECT pg_catalog.pg_start_backup($1, $2, false)",
1066-
2,
1067-
params);
1068-
else
1069-
res = pgut_execute(conn,
1070-
"SELECT pg_catalog.pg_start_backup($1, $2)",
1071-
2,
1072-
params);
1063+
res = pgut_execute(conn,
1064+
"SELECT pg_catalog.pg_backup_start($1, $2)",
1065+
2,
1066+
params);
10731067

10741068
/*
10751069
* Set flag that pg_start_backup() was called. If an error will happen it
@@ -1618,23 +1612,23 @@ pg_stop_backup_send(PGconn *conn, int server_version, bool is_started_on_replica
16181612
"SELECT"
16191613
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
16201614
" current_timestamp(0)::timestamptz,"
1621-
" pg_catalog.pg_stop_backup() as lsn",
1615+
" pg_catalog.pg_backup_stop() as lsn",
16221616
stop_backup_on_master_query[] =
16231617
"SELECT"
16241618
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
16251619
" current_timestamp(0)::timestamptz,"
16261620
" lsn,"
16271621
" labelfile,"
16281622
" spcmapfile"
1629-
" FROM pg_catalog.pg_stop_backup(false, false)",
1623+
" FROM pg_catalog.pg_backup_stop(false)",
16301624
stop_backup_on_master_before10_query[] =
16311625
"SELECT"
16321626
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
16331627
" current_timestamp(0)::timestamptz,"
16341628
" lsn,"
16351629
" labelfile,"
16361630
" spcmapfile"
1637-
" FROM pg_catalog.pg_stop_backup(false)",
1631+
" FROM pg_catalog.pg_backup_stop()",
16381632
/*
16391633
* In case of backup from replica >= 9.6 we do not trust minRecPoint
16401634
* and stop_backup LSN, so we use latest replayed LSN as STOP LSN.
@@ -1646,15 +1640,15 @@ pg_stop_backup_send(PGconn *conn, int server_version, bool is_started_on_replica
16461640
" pg_catalog.pg_last_wal_replay_lsn(),"
16471641
" labelfile,"
16481642
" spcmapfile"
1649-
" FROM pg_catalog.pg_stop_backup(false, false)",
1643+
" FROM pg_catalog.pg_backup_stop(false)",
16501644
stop_backup_on_replica_before10_query[] =
16511645
"SELECT"
16521646
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
16531647
" current_timestamp(0)::timestamptz,"
16541648
" pg_catalog.pg_last_xlog_replay_location(),"
16551649
" labelfile,"
16561650
" spcmapfile"
1657-
" FROM pg_catalog.pg_stop_backup(false)";
1651+
" FROM pg_catalog.pg_backup_stop()";
16581652

16591653
const char * const stop_backup_query =
16601654
is_exclusive ?
@@ -1682,7 +1676,7 @@ pg_stop_backup_send(PGconn *conn, int server_version, bool is_started_on_replica
16821676
*/
16831677
sent = pgut_send(conn, stop_backup_query, 0, NULL, WARNING);
16841678
if (!sent)
1685-
elog(ERROR, "Failed to send pg_stop_backup query");
1679+
elog(ERROR, "Failed to send pg_backup_stop query");
16861680

16871681
/* After we have sent pg_stop_backup, we don't need this callback anymore */
16881682
pgut_atexit_pop(backup_stopbackup_callback, &stop_callback_params);
@@ -1728,7 +1722,7 @@ pg_stop_backup_consume(PGconn *conn, int server_version,
17281722
if (interrupted)
17291723
{
17301724
pgut_cancel(conn);
1731-
elog(ERROR, "interrupted during waiting for pg_stop_backup");
1725+
elog(ERROR, "interrupted during waiting for pg_backup_stop");
17321726
}
17331727

17341728
if (pg_stop_backup_timeout == 1)
@@ -1741,7 +1735,7 @@ pg_stop_backup_consume(PGconn *conn, int server_version,
17411735
if (pg_stop_backup_timeout > timeout)
17421736
{
17431737
pgut_cancel(conn);
1744-
elog(ERROR, "pg_stop_backup doesn't answer in %d seconds, cancel it", timeout);
1738+
elog(ERROR, "pg_backup_stop doesn't answer in %d seconds, cancel it", timeout);
17451739
}
17461740
}
17471741
else
@@ -1753,7 +1747,7 @@ pg_stop_backup_consume(PGconn *conn, int server_version,
17531747

17541748
/* Check successfull execution of pg_stop_backup() */
17551749
if (!query_result)
1756-
elog(ERROR, "pg_stop_backup() failed");
1750+
elog(ERROR, "pg_backup_stop() failed");
17571751
else
17581752
{
17591753
switch (PQresultStatus(query_result))

src/parsexlog.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
* RmgrNames is an array of resource manager names, to make error messages
3030
* a bit nicer.
3131
*/
32-
#if PG_VERSION_NUM >= 100000
32+
#if PG_VERSION_NUM >= 150000
33+
#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup,mask,decode) \
34+
name,
35+
#elif PG_VERSION_NUM >= 100000
3336
#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup,mask) \
3437
name,
3538
#else
@@ -1769,7 +1772,8 @@ extractPageInfo(XLogReaderState *record, XLogReaderData *reader_data,
17691772

17701773
/* Is this a special record type that I recognize? */
17711774

1772-
if (rmid == RM_DBASE_ID && rminfo == XLOG_DBASE_CREATE)
1775+
if (rmid == RM_DBASE_ID
1776+
&& (rminfo == XLOG_DBASE_CREATE_WAL_LOG || rminfo == XLOG_DBASE_CREATE_FILE_COPY))
17731777
{
17741778
/*
17751779
* New databases can be safely ignored. They would be completely
@@ -1823,13 +1827,13 @@ extractPageInfo(XLogReaderState *record, XLogReaderData *reader_data,
18231827
RmgrNames[rmid], info);
18241828
}
18251829

1826-
for (block_id = 0; block_id <= record->max_block_id; block_id++)
1830+
for (block_id = 0; block_id <= record->record->max_block_id; block_id++)
18271831
{
18281832
RelFileNode rnode;
18291833
ForkNumber forknum;
18301834
BlockNumber blkno;
18311835

1832-
if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
1836+
if (!XLogRecGetBlockTagExtended(record, block_id, &rnode, &forknum, &blkno, NULL))
18331837
continue;
18341838

18351839
/* We only care about the main fork; others are copied as is */
@@ -1946,4 +1950,4 @@ static XLogReaderState* WalReaderAllocate(uint32 wal_seg_size, XLogReaderData *r
19461950
#else
19471951
return XLogReaderAllocate(&SimpleXLogPageRead, reader_data);
19481952
#endif
1949-
}
1953+
}

src/stream.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ StreamLog(void *arg)
277277
#if PG_VERSION_NUM >= 150000
278278
ctl.walmethod = CreateWalDirectoryMethod(
279279
stream_arg->basedir,
280-
COMPRESSION_NONE,
280+
PG_COMPRESSION_NONE,
281281
0,
282282
false);
283283
#elif PG_VERSION_NUM >= 100000

src/utils/configuration.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <pwd.h>
2323
#endif
2424
#include <time.h>
25+
#include <pwd.h>
2526

2627
#define MAXPG_LSNCOMPONENT 8
2728

tests/archive.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ def test_pgpro434_3(self):
250250
"--log-level-file=LOG"],
251251
gdb=True)
252252

253+
# Attention! this breakpoint has been set on internal probackup function, not on a postgres core one
253254
gdb.set_breakpoint('pg_stop_backup')
254255
gdb.run_until_break()
255256

@@ -314,6 +315,7 @@ def test_pgpro434_4(self):
314315
"--log-level-file=info"],
315316
gdb=True)
316317

318+
# Attention! this breakpoint has been set on internal probackup function, not on a postgres core one
317319
gdb.set_breakpoint('pg_stop_backup')
318320
gdb.run_until_break()
319321

@@ -341,9 +343,14 @@ def test_pgpro434_4(self):
341343
with open(log_file, 'r') as f:
342344
log_content = f.read()
343345

344-
self.assertIn(
345-
"ERROR: pg_stop_backup doesn't answer in 60 seconds, cancel it",
346-
log_content)
346+
if self.get_version(node) < 150000:
347+
self.assertIn(
348+
"ERROR: pg_stop_backup doesn't answer in 60 seconds, cancel it",
349+
log_content)
350+
else:
351+
self.assertIn(
352+
"ERROR: pg_backup_stop doesn't answer in 60 seconds, cancel it",
353+
log_content)
347354

348355
log_file = os.path.join(node.logs_dir, 'postgresql.log')
349356
with open(log_file, 'r') as f:

tests/auth_test.py

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,29 @@ def test_backup_via_unprivileged_user(self):
5151
1, 0,
5252
"Expecting Error due to missing grant on EXECUTE.")
5353
except ProbackupException as e:
54-
self.assertIn(
55-
"ERROR: query failed: ERROR: permission denied "
56-
"for function pg_start_backup", e.message,
57-
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
58-
repr(e.message), self.cmd))
54+
if self.get_version(node) < 150000:
55+
self.assertIn(
56+
"ERROR: query failed: ERROR: permission denied "
57+
"for function pg_start_backup", e.message,
58+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
59+
repr(e.message), self.cmd))
60+
else:
61+
self.assertIn(
62+
"ERROR: query failed: ERROR: permission denied "
63+
"for function pg_backup_start", e.message,
64+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
65+
repr(e.message), self.cmd))
5966

60-
node.safe_psql(
61-
"postgres",
62-
"GRANT EXECUTE ON FUNCTION"
63-
" pg_start_backup(text, boolean, boolean) TO backup;")
67+
if self.get_version(node) < 150000:
68+
node.safe_psql(
69+
"postgres",
70+
"GRANT EXECUTE ON FUNCTION"
71+
" pg_start_backup(text, boolean, boolean) TO backup;")
72+
else:
73+
node.safe_psql(
74+
"postgres",
75+
"GRANT EXECUTE ON FUNCTION"
76+
" pg_backup_start(text, boolean) TO backup;")
6477

6578
if self.get_version(node) < 100000:
6679
node.safe_psql(
@@ -97,17 +110,24 @@ def test_backup_via_unprivileged_user(self):
97110
1, 0,
98111
"Expecting Error due to missing grant on EXECUTE.")
99112
except ProbackupException as e:
100-
self.assertIn(
101-
"ERROR: query failed: ERROR: permission denied "
102-
"for function pg_stop_backup", e.message,
103-
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
104-
repr(e.message), self.cmd))
113+
if self.get_version(node) < 150000:
114+
self.assertIn(
115+
"ERROR: query failed: ERROR: permission denied "
116+
"for function pg_stop_backup", e.message,
117+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
118+
repr(e.message), self.cmd))
119+
else:
120+
self.assertIn(
121+
"ERROR: query failed: ERROR: permission denied "
122+
"for function pg_backup_stop", e.message,
123+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
124+
repr(e.message), self.cmd))
105125

106126
if self.get_version(node) < self.version_to_num('10.0'):
107127
node.safe_psql(
108128
"postgres",
109129
"GRANT EXECUTE ON FUNCTION pg_stop_backup(boolean) TO backup")
110-
else:
130+
elif self.get_vestion(node) < self.version_to_num('15.0'):
111131
node.safe_psql(
112132
"postgres",
113133
"GRANT EXECUTE ON FUNCTION "
@@ -116,6 +136,16 @@ def test_backup_via_unprivileged_user(self):
116136
node.safe_psql(
117137
"postgres",
118138
"GRANT EXECUTE ON FUNCTION pg_stop_backup() TO backup")
139+
else:
140+
node.safe_psql(
141+
"postgres",
142+
"GRANT EXECUTE ON FUNCTION "
143+
"pg_backup_stop(boolean) TO backup")
144+
# Do this for ptrack backups
145+
node.safe_psql(
146+
"postgres",
147+
"GRANT EXECUTE ON FUNCTION pg_backup_stop() TO backup")
148+
119149

120150
self.backup_node(
121151
backup_dir, 'node', node, options=['-U', 'backup'])
@@ -177,20 +207,37 @@ def setUpClass(cls):
177207
except StartNodeException:
178208
raise unittest.skip("Node hasn't started")
179209

180-
cls.node.safe_psql(
181-
"postgres",
182-
"CREATE ROLE backup WITH LOGIN PASSWORD 'password'; "
183-
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
184-
"GRANT EXECUTE ON FUNCTION current_setting(text) TO backup; "
185-
"GRANT EXECUTE ON FUNCTION pg_is_in_recovery() TO backup; "
186-
"GRANT EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) TO backup; "
187-
"GRANT EXECUTE ON FUNCTION pg_stop_backup() TO backup; "
188-
"GRANT EXECUTE ON FUNCTION pg_stop_backup(boolean) TO backup; "
189-
"GRANT EXECUTE ON FUNCTION pg_create_restore_point(text) TO backup; "
190-
"GRANT EXECUTE ON FUNCTION pg_switch_xlog() TO backup; "
191-
"GRANT EXECUTE ON FUNCTION txid_current() TO backup; "
192-
"GRANT EXECUTE ON FUNCTION txid_current_snapshot() TO backup; "
193-
"GRANT EXECUTE ON FUNCTION txid_snapshot_xmax(txid_snapshot) TO backup;")
210+
if cls.pb.get_version(cls.node) < 150000:
211+
cls.node.safe_psql(
212+
"postgres",
213+
"CREATE ROLE backup WITH LOGIN PASSWORD 'password'; "
214+
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
215+
"GRANT EXECUTE ON FUNCTION current_setting(text) TO backup; "
216+
"GRANT EXECUTE ON FUNCTION pg_is_in_recovery() TO backup; "
217+
"GRANT EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) TO backup; "
218+
"GRANT EXECUTE ON FUNCTION pg_stop_backup() TO backup; "
219+
"GRANT EXECUTE ON FUNCTION pg_stop_backup(boolean) TO backup; "
220+
"GRANT EXECUTE ON FUNCTION pg_create_restore_point(text) TO backup; "
221+
"GRANT EXECUTE ON FUNCTION pg_switch_xlog() TO backup; "
222+
"GRANT EXECUTE ON FUNCTION txid_current() TO backup; "
223+
"GRANT EXECUTE ON FUNCTION txid_current_snapshot() TO backup; "
224+
"GRANT EXECUTE ON FUNCTION txid_snapshot_xmax(txid_snapshot) TO backup;")
225+
else:
226+
cls.node.safe_psql(
227+
"postgres",
228+
"CREATE ROLE backup WITH LOGIN PASSWORD 'password'; "
229+
"GRANT USAGE ON SCHEMA pg_catalog TO backup; "
230+
"GRANT EXECUTE ON FUNCTION current_setting(text) TO backup; "
231+
"GRANT EXECUTE ON FUNCTION pg_is_in_recovery() TO backup; "
232+
"GRANT EXECUTE ON FUNCTION pg_backup_start(text, boolean) TO backup; "
233+
"GRANT EXECUTE ON FUNCTION pg_backup_stop() TO backup; "
234+
"GRANT EXECUTE ON FUNCTION pg_backup_stop(boolean) TO backup; "
235+
"GRANT EXECUTE ON FUNCTION pg_create_restore_point(text) TO backup; "
236+
"GRANT EXECUTE ON FUNCTION pg_switch_xlog() TO backup; "
237+
"GRANT EXECUTE ON FUNCTION txid_current() TO backup; "
238+
"GRANT EXECUTE ON FUNCTION txid_current_snapshot() TO backup; "
239+
"GRANT EXECUTE ON FUNCTION txid_snapshot_xmax(txid_snapshot) TO backup;")
240+
194241
cls.pgpass_file = os.path.join(os.path.expanduser('~'), '.pgpass')
195242

196243
@classmethod

0 commit comments

Comments
 (0)