Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit856e110

Browse files
committed
Start work on restore tests.
1 parent3c82429 commit856e110

File tree

3 files changed

+358
-2
lines changed

3 files changed

+358
-2
lines changed

‎tests/__init__.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
importunittest
22

3-
from .importinit_test,option_test,show_test,backup_test,delete_test
3+
from .importinit_test,option_test,show_test,backup_test,delete_test,restore_test
44

55

66
defload_tests(loader,tests,pattern):
@@ -10,5 +10,6 @@ def load_tests(loader, tests, pattern):
1010
suite.addTests(loader.loadTestsFromModule(show_test))
1111
suite.addTests(loader.loadTestsFromModule(backup_test))
1212
suite.addTests(loader.loadTestsFromModule(delete_test))
13+
suite.addTests(loader.loadTestsFromModule(restore_test))
1314

1415
returnsuite

‎tests/pb_lib.py‎

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,31 @@ def __init__(self, split_line):
3535
classProbackupTest(object):
3636
def__init__(self,*args,**kwargs):
3737
super(ProbackupTest,self).__init__(*args,**kwargs)
38+
self.test_env=os.environ.copy()
39+
envs_list= [
40+
"LANGUAGE",
41+
"LC_ALL",
42+
"PGCONNECT_TIMEOUT",
43+
"PGDATA",
44+
"PGDATABASE",
45+
"PGHOSTADDR",
46+
"PGREQUIRESSL",
47+
"PGSERVICE",
48+
"PGSSLMODE",
49+
"PGUSER",
50+
"PGPORT",
51+
"PGHOST"
52+
]
53+
54+
foreinenvs_list:
55+
try:
56+
delself.test_env[e]
57+
except:
58+
pass
59+
60+
self.test_env["LC_MESSAGES"]="C"
61+
self.test_env["LC_TIME"]="C"
62+
3863
self.dir_path=path.dirname(os.path.realpath(__file__))
3964
try:
4065
os.makedirs(path.join(self.dir_path,"tmp_dirs"))
@@ -73,7 +98,8 @@ def run_pb(self, command):
7398
try:
7499
returnsubprocess.check_output(
75100
[self.probackup_path]+command,
76-
stderr=subprocess.STDOUT
101+
stderr=subprocess.STDOUT,
102+
env=self.test_env
77103
)
78104
exceptsubprocess.CalledProcessErroraserr:
79105
returnerr.output
@@ -102,6 +128,18 @@ def backup_pb(self, node, backup_type="full", options=[]):
102128
# print(cmd_list)
103129
returnself.run_pb(cmd_list+options)
104130

131+
defrestore_pb(self,node,id=None,options=[]):
132+
cmd_list= [
133+
"-D",node.data_dir,
134+
"-B",self.backup_dir(node),
135+
"restore"
136+
]
137+
ifid:
138+
cmd_list.append(id)
139+
140+
# print(cmd_list)
141+
returnself.run_pb(cmd_list+options)
142+
105143
defshow_pb(self,node,id=None,options=[],as_text=False):
106144
cmd_list= [
107145
"-B",self.backup_dir(node),
@@ -137,3 +175,28 @@ def delete_pb(self, node, id=None, options=[]):
137175

138176
# print(cmd_list)
139177
returnself.run_pb(options+cmd_list)
178+
179+
defget_control_data(self,node):
180+
pg_controldata=node.get_bin_path("pg_controldata")
181+
out_data= {}
182+
lines=subprocess.check_output(
183+
[pg_controldata]+ ["-D",node.data_dir],
184+
stderr=subprocess.STDOUT,
185+
env=self.test_env
186+
).splitlines()
187+
forlinlines:
188+
key,value=l.split(b":",maxsplit=1)
189+
out_data[key.strip()]=value.strip()
190+
returnout_data
191+
192+
defget_recovery_conf(self,node):
193+
out_dict= {}
194+
withopen(path.join(node.data_dir,"recovery.conf"),"r")asrecovery_conf:
195+
forlineinrecovery_conf:
196+
try:
197+
key,value=line.split("=")
198+
except:
199+
continue
200+
out_dict[key.strip()]=value.strip(" '").replace("'\n","")
201+
202+
returnout_dict

‎tests/restore_test.py‎

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
importunittest
2+
fromosimportpath
3+
importsix
4+
from .pb_libimportProbackupTest
5+
fromtestgresimportstop_all
6+
importsubprocess
7+
fromdatetimeimportdatetime
8+
9+
10+
classRestoreTest(ProbackupTest,unittest.TestCase):
11+
12+
def__init__(self,*args,**kwargs):
13+
super(RestoreTest,self).__init__(*args,**kwargs)
14+
15+
@classmethod
16+
deftearDownClass(cls):
17+
stop_all()
18+
19+
deftest_restore_to_latest_1(self):
20+
"""recovery to latest from full backup"""
21+
node=self.make_bnode('restore_to_latest_1',base_dir="tmp_dirs/restore/restore_to_latest_1")
22+
node.start()
23+
self.assertEqual(self.init_pb(node),six.b(""))
24+
node.pgbench_init(scale=2)
25+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
26+
pgbench.wait()
27+
pgbench.stdout.close()
28+
before=node.execute("postgres","SELECT * FROM pgbench_branches")
29+
withopen(path.join(node.logs_dir,"backup_1.log"),"wb")asbackup_log:
30+
backup_log.write(self.backup_pb(node,options=["--verbose"]))
31+
32+
node.pg_ctl("stop", {
33+
"-D":node.data_dir,
34+
"-w":None,
35+
"-m":"immediate"
36+
})
37+
38+
withopen(path.join(node.logs_dir,"restore_1.log"),"wb")asrestore_log:
39+
restore_log.write(self.restore_pb(node,options=["-j","4","--verbose"]))
40+
41+
node.pg_ctl("start", {
42+
"-D":node.data_dir,
43+
"-w":None,
44+
"-t":"600"
45+
})
46+
47+
after=node.execute("postgres","SELECT * FROM pgbench_branches")
48+
self.assertEqual(before,after)
49+
50+
node.stop()
51+
52+
deftest_restore_to_latest_2(self):
53+
"""recovery to latest from full + page backups"""
54+
node=self.make_bnode('restore_to_latest_2',base_dir="tmp_dirs/restore/restore_to_latest_2")
55+
node.start()
56+
self.assertEqual(self.init_pb(node),six.b(""))
57+
node.pgbench_init(scale=2)
58+
59+
withopen(path.join(node.logs_dir,"backup_1.log"),"wb")asbackup_log:
60+
backup_log.write(self.backup_pb(node,options=["--verbose"]))
61+
62+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
63+
pgbench.wait()
64+
pgbench.stdout.close()
65+
66+
withopen(path.join(node.logs_dir,"backup_2.log"),"wb")asbackup_log:
67+
backup_log.write(self.backup_pb(node,backup_type="page",options=["--verbose"]))
68+
69+
before=node.execute("postgres","SELECT * FROM pgbench_branches")
70+
71+
node.pg_ctl("stop", {
72+
"-D":node.data_dir,
73+
"-w":None,
74+
"-m":"immediate"
75+
})
76+
77+
withopen(path.join(node.logs_dir,"restore_1.log"),"wb")asrestore_log:
78+
restore_log.write(self.restore_pb(node,options=["-j","4","--verbose"]))
79+
80+
node.pg_ctl("start", {
81+
"-D":node.data_dir,
82+
"-w":None,
83+
"-t":"600"
84+
})
85+
86+
after=node.execute("postgres","SELECT * FROM pgbench_branches")
87+
self.assertEqual(before,after)
88+
89+
node.stop()
90+
91+
deftest_restore_to_timeline_3(self):
92+
"""recovery to target timeline"""
93+
node=self.make_bnode('restore_to_timeline_3',base_dir="tmp_dirs/restore/restore_to_timeline_3")
94+
node.start()
95+
self.assertEqual(self.init_pb(node),six.b(""))
96+
node.pgbench_init(scale=2)
97+
98+
before=node.execute("postgres","SELECT * FROM pgbench_branches")
99+
100+
withopen(path.join(node.logs_dir,"backup_1.log"),"wb")asbackup_log:
101+
backup_log.write(self.backup_pb(node,backup_type="full",options=["--verbose"]))
102+
103+
target_tli=int(self.get_control_data(node)[six.b("Latest checkpoint's TimeLineID")])
104+
node.pg_ctl("stop", {
105+
"-D":node.data_dir,
106+
"-w":None,
107+
"-m":"immediate"
108+
})
109+
110+
withopen(path.join(node.logs_dir,"restore_1.log"),"wb")asrestore_log:
111+
restore_log.write(self.restore_pb(node,options=["-j","4","--verbose"]))
112+
113+
node.pg_ctl("start", {
114+
"-D":node.data_dir,
115+
"-w":None,
116+
"-t":"600"
117+
})
118+
119+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
120+
pgbench.wait()
121+
pgbench.stdout.close()
122+
123+
withopen(path.join(node.logs_dir,"backup_2.log"),"wb")asbackup_log:
124+
backup_log.write(self.backup_pb(node,backup_type="full",options=["--verbose"]))
125+
126+
node.pg_ctl("stop", {
127+
"-D":node.data_dir,
128+
"-w":None,
129+
"-m":"immediate"
130+
})
131+
132+
withopen(path.join(node.logs_dir,"restore_2.log"),"wb")asrestore_log:
133+
restore_log.write(self.restore_pb(
134+
node,
135+
options=["-j","4","--verbose","--timeline=%i"%target_tli]
136+
))
137+
138+
recovery_target_timeline=self.get_recovery_conf(node)["recovery_target_timeline"]
139+
self.assertEqual(int(recovery_target_timeline),target_tli)
140+
141+
node.pg_ctl("start", {
142+
"-D":node.data_dir,
143+
"-w":None,
144+
"-t":"600"
145+
})
146+
147+
after=node.execute("postgres","SELECT * FROM pgbench_branches")
148+
self.assertEqual(before,after)
149+
150+
node.stop()
151+
152+
deftest_restore_to_time_4(self):
153+
"""recovery to target timeline"""
154+
node=self.make_bnode('restore_to_time_4',base_dir="tmp_dirs/restore/restore_to_time_4")
155+
node.start()
156+
self.assertEqual(self.init_pb(node),six.b(""))
157+
node.pgbench_init(scale=2)
158+
159+
before=node.execute("postgres","SELECT * FROM pgbench_branches")
160+
161+
withopen(path.join(node.logs_dir,"backup_1.log"),"wb")asbackup_log:
162+
backup_log.write(self.backup_pb(node,backup_type="full",options=["--verbose"]))
163+
164+
target_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
165+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
166+
pgbench.wait()
167+
pgbench.stdout.close()
168+
169+
node.pg_ctl("stop", {
170+
"-D":node.data_dir,
171+
"-w":None,
172+
"-m":"immediate"
173+
})
174+
175+
withopen(path.join(node.logs_dir,"restore_1.log"),"wb")asrestore_log:
176+
restore_log.write(self.restore_pb(
177+
node,
178+
options=["-j","4","--verbose",'--time="%s"'%target_time]
179+
))
180+
181+
node.pg_ctl("start", {
182+
"-D":node.data_dir,
183+
"-w":None,
184+
"-t":"600"
185+
})
186+
187+
after=node.execute("postgres","SELECT * FROM pgbench_branches")
188+
self.assertEqual(before,after)
189+
190+
node.stop()
191+
192+
deftest_restore_to_xid_5(self):
193+
"""recovery to target xid"""
194+
node=self.make_bnode('restore_to_xid_5',base_dir="tmp_dirs/restore/restore_to_xid_5")
195+
node.start()
196+
self.assertEqual(self.init_pb(node),six.b(""))
197+
node.pgbench_init(scale=2)
198+
withnode.connect("postgres")ascon:
199+
con.execute("CREATE TABLE tbl0005 (a text)")
200+
con.commit()
201+
202+
withopen(path.join(node.logs_dir,"backup_1.log"),"wb")asbackup_log:
203+
backup_log.write(self.backup_pb(node,backup_type="full",options=["--verbose"]))
204+
205+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
206+
pgbench.wait()
207+
pgbench.stdout.close()
208+
209+
before=node.execute("postgres","SELECT * FROM pgbench_branches")
210+
withnode.connect("postgres")ascon:
211+
res=con.execute("INSERT INTO tbl0005 VALUES ('inserted') RETURNING (xmin)")
212+
con.commit()
213+
target_xid=res[0][0]
214+
215+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
216+
pgbench.wait()
217+
pgbench.stdout.close()
218+
219+
# Enforce segment to be archived to ensure that recovery goes up to the
220+
# wanted point. There is no way to ensure that all segments needed have
221+
# been archived up to the xmin point saved earlier without that.
222+
node.execute("postgres","SELECT pg_switch_xlog()")
223+
224+
node.pg_ctl("stop", {
225+
"-D":node.data_dir,
226+
"-w":None,
227+
"-m":"fast"
228+
})
229+
230+
withopen(path.join(node.logs_dir,"restore_1.log"),"wb")asrestore_log:
231+
restore_log.write(self.restore_pb(
232+
node,
233+
options=["-j","4","--verbose",'--xid=%s'%target_xid]
234+
))
235+
236+
node.pg_ctl("start", {
237+
"-D":node.data_dir,
238+
"-w":None,
239+
"-t":"600"
240+
})
241+
242+
after=node.execute("postgres","SELECT * FROM pgbench_branches")
243+
self.assertEqual(before,after)
244+
245+
node.stop()
246+
247+
deftest_restore_full_ptrack_6(self):
248+
"""recovery to latest from full + ptrack backups"""
249+
node=self.make_bnode('restore_full_ptrack_6',base_dir="tmp_dirs/restore/restore_full_ptrack_6")
250+
node.start()
251+
self.assertEqual(self.init_pb(node),six.b(""))
252+
node.pgbench_init(scale=2)
253+
is_ptrack=node.execute("postgres","SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
254+
ifnotis_ptrack:
255+
node.stop()
256+
self.skipTest("ptrack not supported")
257+
return
258+
259+
node.append_conf("postgresql.conf","ptrack_enable = on")
260+
node.restart()
261+
262+
withopen(path.join(node.logs_dir,"backup_1.log"),"wb")asbackup_log:
263+
backup_log.write(self.backup_pb(node,backup_type="full",options=["--verbose"]))
264+
265+
pgbench=node.pgbench(stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
266+
pgbench.wait()
267+
pgbench.stdout.close()
268+
269+
withopen(path.join(node.logs_dir,"backup_2.log"),"wb")asbackup_log:
270+
backup_log.write(self.backup_pb(node,backup_type="ptrack",options=["--verbose"]))
271+
272+
before=node.execute("postgres","SELECT * FROM pgbench_branches")
273+
274+
node.pg_ctl("stop", {
275+
"-D":node.data_dir,
276+
"-w":None,
277+
"-m":"immediate"
278+
})
279+
280+
withopen(path.join(node.logs_dir,"restore_1.log"),"wb")asrestore_log:
281+
restore_log.write(self.restore_pb(node,options=["-j","4","--verbose"]))
282+
283+
node.pg_ctl("start", {
284+
"-D":node.data_dir,
285+
"-w":None,
286+
"-t":"600"
287+
})
288+
289+
after=node.execute("postgres","SELECT * FROM pgbench_branches")
290+
self.assertEqual(before,after)
291+
292+
node.stop()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp