@@ -12,10 +12,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
12
12
# @unittest.expectedFailure
13
13
def test_ptrack_truncate (self ):
14
14
fname = self .id ().split ('.' )[3 ]
15
- node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (module_name , fname ),
15
+ node = self .make_simple_node (
16
+ base_dir = "{0}/{1}/node" .format (module_name , fname ),
16
17
set_replication = True ,
17
18
initdb_params = ['--data-checksums' ],
18
- pg_options = {'ptrack_enable' : 'on' , 'wal_level' : 'replica' , 'max_wal_senders' : '2' })
19
+ pg_options = {
20
+ 'ptrack_enable' : 'on' ,
21
+ 'wal_level' : 'replica' ,
22
+ 'max_wal_senders' : '2' })
23
+
19
24
backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
20
25
self .init_pb (backup_dir )
21
26
self .add_instance (backup_dir , 'node' , node )
@@ -26,11 +31,19 @@ def test_ptrack_truncate(self):
26
31
# Create table and indexes
27
32
node .safe_psql (
28
33
"postgres" ,
29
- "create sequence t_seq; create table t_heap tablespace somedata as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,256) i" )
34
+ "create sequence t_seq; create table t_heap tablespace somedata "
35
+ "as select i as id, md5(i::text) as text, "
36
+ "md5(repeat(i::text,10))::tsvector as tsvector "
37
+ "from generate_series(0,2560) i" )
38
+
30
39
for i in idx_ptrack :
31
40
if idx_ptrack [i ]['type' ] != 'heap' and idx_ptrack [i ]['type' ] != 'seq' :
32
- node .safe_psql ("postgres" , "create index {0} on {1} using {2}({3}) tablespace somedata" .format (
33
- i , idx_ptrack [i ]['relation' ], idx_ptrack [i ]['type' ], idx_ptrack [i ]['column' ]))
41
+ node .safe_psql (
42
+ "postgres" ,
43
+ "create index {0} on {1} using {2}({3}) "
44
+ "tablespace somedata" .format (
45
+ i , idx_ptrack [i ]['relation' ],
46
+ idx_ptrack [i ]['type' ], idx_ptrack [i ]['column' ]))
34
47
35
48
node .safe_psql ('postgres' , 'truncate t_heap' )
36
49
node .safe_psql ('postgres' , 'checkpoint' )
@@ -45,7 +58,8 @@ def test_ptrack_truncate(self):
45
58
idx_ptrack [i ]['path' ], idx_ptrack [i ]['old_size' ])
46
59
47
60
# Make full backup to clean every ptrack
48
- self .backup_node (backup_dir , 'node' , node , options = ['-j10' , '--stream' ])
61
+ self .backup_node (
62
+ backup_dir , 'node' , node , options = ['-j10' , '--stream' ])
49
63
for i in idx_ptrack :
50
64
idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
51
65
node , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ]])
@@ -57,18 +71,25 @@ def test_ptrack_truncate(self):
57
71
# @unittest.skip("skip")
58
72
def test_ptrack_truncate_replica (self ):
59
73
fname = self .id ().split ('.' )[3 ]
60
- master = self .make_simple_node (base_dir = "{0}/{1}/master" .format (module_name , fname ),
74
+ master = self .make_simple_node (
75
+ base_dir = "{0}/{1}/master" .format (module_name , fname ),
61
76
set_replication = True ,
62
77
initdb_params = ['--data-checksums' ],
63
- pg_options = {'ptrack_enable' : 'on' , 'wal_level' : 'replica' , 'max_wal_senders' : '2' })
78
+ pg_options = {
79
+ 'ptrack_enable' : 'on' ,
80
+ 'wal_level' : 'replica' ,
81
+ 'max_wal_senders' : '2' ,
82
+ 'checkpoint_timeout' : '30' })
83
+
64
84
backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
65
85
self .init_pb (backup_dir )
66
86
self .add_instance (backup_dir , 'master' , master )
67
87
master .start ()
68
88
69
89
self .backup_node (backup_dir , 'master' , master , options = ['--stream' ])
70
90
71
- replica = self .make_simple_node (base_dir = "{0}/{1}/replica" .format (module_name , fname ))
91
+ replica = self .make_simple_node (
92
+ base_dir = "{0}/{1}/replica" .format (module_name , fname ))
72
93
replica .cleanup ()
73
94
74
95
self .restore_node (backup_dir , 'master' , replica )
@@ -81,15 +102,30 @@ def test_ptrack_truncate_replica(self):
81
102
# Create table and indexes
82
103
master .safe_psql (
83
104
"postgres" ,
84
- "create sequence t_seq; create table t_heap tablespace somedata as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,256) i" )
105
+ "create sequence t_seq; create table t_heap tablespace somedata "
106
+ "as select i as id, md5(i::text) as text, "
107
+ "md5(repeat(i::text,10))::tsvector as tsvector "
108
+ "from generate_series(0,2560) i" )
85
109
for i in idx_ptrack :
86
110
if idx_ptrack [i ]['type' ] != 'heap' and idx_ptrack [i ]['type' ] != 'seq' :
87
- master .safe_psql ("postgres" , "create index {0} on {1} using {2}({3}) tablespace somedata" .format (
88
- i , idx_ptrack [i ]['relation' ], idx_ptrack [i ]['type' ], idx_ptrack [i ]['column' ]))
111
+ master .safe_psql (
112
+ "postgres" , "create index {0} on {1} using {2}({3}) "
113
+ "tablespace somedata" .format (
114
+ i , idx_ptrack [i ]['relation' ],
115
+ idx_ptrack [i ]['type' ], idx_ptrack [i ]['column' ]))
89
116
90
117
replica .safe_psql ('postgres' , 'truncate t_heap' )
91
118
replica .safe_psql ('postgres' , 'checkpoint' )
92
119
120
+ # Sync master and replica
121
+ lsn = master .safe_psql (
122
+ 'postgres' , 'SELECT pg_catalog.pg_current_wal_lsn()' ).rstrip ()
123
+ replica .poll_query_until (
124
+ "postgres" ,
125
+ "SELECT '{0}'::pg_lsn <= pg_last_wal_replay_lsn()" .format (
126
+ lsn ))
127
+ replica .safe_psql ('postgres' , 'checkpoint' )
128
+
93
129
for i in idx_ptrack :
94
130
# get fork size and calculate it in pages
95
131
idx_ptrack [i ]['old_size' ] = self .get_fork_size (replica , i )
@@ -100,7 +136,8 @@ def test_ptrack_truncate_replica(self):
100
136
idx_ptrack [i ]['path' ], idx_ptrack [i ]['old_size' ])
101
137
102
138
# Make full backup to clean every ptrack
103
- self .backup_node (backup_dir , 'replica' , replica , options = ['-j10' , '--stream' ])
139
+ self .backup_node (
140
+ backup_dir , 'replica' , replica , options = ['-j10' , '--stream' ])
104
141
for i in idx_ptrack :
105
142
idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
106
143
replica , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ]])
@@ -111,6 +148,17 @@ def test_ptrack_truncate_replica(self):
111
148
master .safe_psql ('postgres' , 'vacuum t_heap' )
112
149
master .safe_psql ('postgres' , 'checkpoint' )
113
150
151
+ # Sync master and replica
152
+ lsn = master .safe_psql (
153
+ 'postgres' , 'SELECT pg_catalog.pg_current_wal_lsn()' ).rstrip ()
154
+ replica .poll_query_until (
155
+ "postgres" ,
156
+ "SELECT '{0}'::pg_lsn <= pg_last_wal_replay_lsn()" .format (
157
+ lsn ))
158
+ replica .safe_psql ('postgres' , 'checkpoint' )
159
+
160
+ # CHECK PTRACK SANITY
161
+ success = True
114
162
for i in idx_ptrack :
115
163
# get new size of heap and indexes and calculate it in pages
116
164
idx_ptrack [i ]['new_size' ] = self .get_fork_size (replica , i )
@@ -121,10 +169,16 @@ def test_ptrack_truncate_replica(self):
121
169
idx_ptrack [i ]['path' ], idx_ptrack [i ]['new_size' ])
122
170
# get ptrack for every idx
123
171
idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
124
- replica , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ], idx_ptrack [i ]['new_size' ]])
172
+ replica , idx_ptrack [i ]['path' ],
173
+ [idx_ptrack [i ]['old_size' ], idx_ptrack [i ]['new_size' ]])
125
174
126
175
# compare pages and check ptrack sanity
127
- self .check_ptrack_sanity (idx_ptrack [i ])
176
+ if not self .check_ptrack_sanity (idx_ptrack [i ]):
177
+ success = False
178
+
179
+ self .assertTrue (
180
+ success , 'Ptrack has failed to register changes in data files'
181
+ )
128
182
129
183
# Clean after yourself
130
184
self .del_test_dir (module_name , fname )
0 commit comments