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)
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