@@ -12,10 +12,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
1212 # @unittest.expectedFailure
1313 def test_ptrack_truncate (self ):
1414 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 ),
1617 set_replication = True ,
1718 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+
1924 backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
2025 self .init_pb (backup_dir )
2126 self .add_instance (backup_dir , 'node' , node )
@@ -26,11 +31,19 @@ def test_ptrack_truncate(self):
2631 # Create table and indexes
2732 node .safe_psql (
2833 "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+
3039 for i in idx_ptrack :
3140 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' ]))
3447
3548 node .safe_psql ('postgres' , 'truncate t_heap' )
3649 node .safe_psql ('postgres' , 'checkpoint' )
@@ -45,7 +58,8 @@ def test_ptrack_truncate(self):
4558 idx_ptrack [i ]['path' ], idx_ptrack [i ]['old_size' ])
4659
4760 # 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' ])
4963 for i in idx_ptrack :
5064 idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
5165 node , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ]])
@@ -57,18 +71,25 @@ def test_ptrack_truncate(self):
5771 # @unittest.skip("skip")
5872 def test_ptrack_truncate_replica (self ):
5973 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 ),
6176 set_replication = True ,
6277 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+
6484 backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
6585 self .init_pb (backup_dir )
6686 self .add_instance (backup_dir , 'master' , master )
6787 master .start ()
6888
6989 self .backup_node (backup_dir , 'master' , master , options = ['--stream' ])
7090
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 ))
7293 replica .cleanup ()
7394
7495 self .restore_node (backup_dir , 'master' , replica )
@@ -81,15 +102,30 @@ def test_ptrack_truncate_replica(self):
81102 # Create table and indexes
82103 master .safe_psql (
83104 "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" )
85109 for i in idx_ptrack :
86110 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' ]))
89116
90117 replica .safe_psql ('postgres' , 'truncate t_heap' )
91118 replica .safe_psql ('postgres' , 'checkpoint' )
92119
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+
93129 for i in idx_ptrack :
94130 # get fork size and calculate it in pages
95131 idx_ptrack [i ]['old_size' ] = self .get_fork_size (replica , i )
@@ -100,7 +136,8 @@ def test_ptrack_truncate_replica(self):
100136 idx_ptrack [i ]['path' ], idx_ptrack [i ]['old_size' ])
101137
102138 # 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' ])
104141 for i in idx_ptrack :
105142 idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
106143 replica , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ]])
@@ -111,6 +148,17 @@ def test_ptrack_truncate_replica(self):
111148 master .safe_psql ('postgres' , 'vacuum t_heap' )
112149 master .safe_psql ('postgres' , 'checkpoint' )
113150
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
114162 for i in idx_ptrack :
115163 # get new size of heap and indexes and calculate it in pages
116164 idx_ptrack [i ]['new_size' ] = self .get_fork_size (replica , i )
@@ -121,10 +169,16 @@ def test_ptrack_truncate_replica(self):
121169 idx_ptrack [i ]['path' ], idx_ptrack [i ]['new_size' ])
122170 # get ptrack for every idx
123171 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' ]])
125174
126175 # 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+ )
128182
129183 # Clean after yourself
130184 self .del_test_dir (module_name , fname )
0 commit comments