1
1
import os
2
2
import unittest
3
3
from .helpers .ptrack_helpers import ProbackupTest , idx_ptrack
4
+ import time
4
5
5
6
6
7
module_name = 'ptrack_vacuum_full'
@@ -12,10 +13,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
12
13
# @unittest.expectedFailure
13
14
def test_ptrack_vacuum_full (self ):
14
15
fname = self .id ().split ('.' )[3 ]
15
- node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (module_name , fname ),
16
+ node = self .make_simple_node (
17
+ base_dir = "{0}/{1}/node" .format (module_name , fname ),
16
18
set_replication = True ,
17
19
initdb_params = ['--data-checksums' ],
18
- pg_options = {'ptrack_enable' : 'on' , 'wal_level' : 'replica' , 'max_wal_senders' : '2' })
20
+ pg_options = {
21
+ 'ptrack_enable' : 'on' ,
22
+ 'wal_level' : 'replica' ,
23
+ 'max_wal_senders' : '2' })
24
+
19
25
backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
20
26
self .init_pb (backup_dir )
21
27
self .add_instance (backup_dir , 'node' , node )
@@ -26,11 +32,17 @@ def test_ptrack_vacuum_full(self):
26
32
# Create table and indexes
27
33
res = node .safe_psql (
28
34
"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,127) i" )
35
+ "create sequence t_seq; create table t_heap tablespace somedata "
36
+ "as select i as id, md5(i::text) as text, "
37
+ "md5(repeat(i::text,10))::tsvector as tsvector "
38
+ "from generate_series(0,127) i" )
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" , "create index {0} on {1} "
43
+ "using {2}({3}) tablespace somedata" .format (
44
+ i , idx_ptrack [i ]['relation' ],
45
+ idx_ptrack [i ]['type' ], idx_ptrack [i ]['column' ]))
34
46
35
47
node .safe_psql ('postgres' , 'vacuum t_heap' )
36
48
node .safe_psql ('postgres' , 'checkpoint' )
@@ -44,7 +56,8 @@ def test_ptrack_vacuum_full(self):
44
56
idx_ptrack [i ]['old_pages' ] = self .get_md5_per_page_for_fork (
45
57
idx_ptrack [i ]['path' ], idx_ptrack [i ]['old_size' ])
46
58
47
- self .backup_node (backup_dir , 'node' , node , options = ['-j10' , '--stream' ])
59
+ self .backup_node (
60
+ backup_dir , 'node' , node , options = ['-j10' , '--stream' ])
48
61
49
62
node .safe_psql ('postgres' , 'delete from t_heap where id%2 = 1' )
50
63
node .safe_psql ('postgres' , 'vacuum full t_heap' )
@@ -60,7 +73,8 @@ def test_ptrack_vacuum_full(self):
60
73
idx_ptrack [i ]['path' ], idx_ptrack [i ]['new_size' ])
61
74
# get ptrack for every idx
62
75
idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
63
- node , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ], idx_ptrack [i ]['new_size' ]])
76
+ node , idx_ptrack [i ]['path' ],
77
+ [idx_ptrack [i ]['old_size' ], idx_ptrack [i ]['new_size' ]])
64
78
65
79
# compare pages and check ptrack sanity, the most important part
66
80
self .check_ptrack_sanity (idx_ptrack [i ])
@@ -72,17 +86,23 @@ def test_ptrack_vacuum_full(self):
72
86
# @unittest.expectedFailure
73
87
def test_ptrack_vacuum_full_replica (self ):
74
88
fname = self .id ().split ('.' )[3 ]
75
- master = self .make_simple_node (base_dir = "{0}/{1}/master" .format (module_name , fname ),
89
+ master = self .make_simple_node (
90
+ base_dir = "{0}/{1}/master" .format (module_name , fname ),
76
91
set_replication = True ,
77
92
initdb_params = ['--data-checksums' ],
78
- pg_options = {'ptrack_enable' : 'on' , 'wal_level' : 'replica' , 'max_wal_senders' : '2' })
93
+ pg_options = {
94
+ 'ptrack_enable' : 'on' , 'wal_level' : 'replica' ,
95
+ 'max_wal_senders' : '2' , 'autovacuum' : 'off' ,
96
+ 'checkpoint_timeout' : '30s' }
97
+ )
79
98
backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
80
99
self .init_pb (backup_dir )
81
100
self .add_instance (backup_dir , 'master' , master )
82
101
master .start ()
83
102
84
103
self .backup_node (backup_dir , 'master' , master , options = ['--stream' ])
85
- replica = self .make_simple_node (base_dir = "{0}/{1}/replica" .format (module_name , fname ))
104
+ replica = self .make_simple_node (
105
+ base_dir = "{0}/{1}/replica" .format (module_name , fname ))
86
106
replica .cleanup ()
87
107
88
108
self .restore_node (backup_dir , 'master' , replica )
@@ -95,15 +115,32 @@ def test_ptrack_vacuum_full_replica(self):
95
115
# Create table and indexes
96
116
master .safe_psql (
97
117
"postgres" ,
98
- "create sequence t_seq; create table t_heap as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,127) i" )
118
+ "create sequence t_seq; create table t_heap as select i as id, "
119
+ "md5(i::text) as text, md5(repeat(i::text,10))::tsvector as "
120
+ "tsvector from generate_series(0,127) i" )
99
121
for i in idx_ptrack :
100
122
if idx_ptrack [i ]['type' ] != 'heap' and idx_ptrack [i ]['type' ] != 'seq' :
101
- master .safe_psql ("postgres" , "create index {0} on {1} using {2}({3})" .format (
102
- i , idx_ptrack [i ]['relation' ], idx_ptrack [i ]['type' ], idx_ptrack [i ]['column' ]))
123
+ master .safe_psql (
124
+ "postgres" ,
125
+ "create index {0} on {1} using {2}({3})" .format (
126
+ i , idx_ptrack [i ]['relation' ],
127
+ idx_ptrack [i ]['type' ],
128
+ idx_ptrack [i ]['column' ]))
103
129
104
130
master .safe_psql ('postgres' , 'vacuum t_heap' )
105
131
master .safe_psql ('postgres' , 'checkpoint' )
106
132
133
+ # Sync master and replica
134
+ lsn = master .safe_psql (
135
+ 'postgres' , 'SELECT pg_catalog.pg_current_wal_lsn()' ).rstrip ()
136
+ # print(lsn)
137
+
138
+ replica .poll_query_until (
139
+ "postgres" ,
140
+ "SELECT '{0}'::pg_lsn <= pg_last_wal_replay_lsn()" .format (
141
+ lsn ))
142
+ replica .safe_psql ('postgres' , 'checkpoint' )
143
+
107
144
for i in idx_ptrack :
108
145
# get size of heap and indexes. size calculated in pages
109
146
idx_ptrack [i ]['old_size' ] = self .get_fork_size (replica , i )
@@ -114,12 +151,34 @@ def test_ptrack_vacuum_full_replica(self):
114
151
idx_ptrack [i ]['path' ], idx_ptrack [i ]['old_size' ])
115
152
116
153
# Take FULL backup to clean every ptrack
117
- self .backup_node (backup_dir , 'replica' , replica , options = ['-j10' ,
118
- '--master-host=localhost' , '--master-db=postgres' , '--master-port={0}' .format (master .port )])
154
+ self .backup_node (
155
+ backup_dir , 'replica' , replica ,
156
+ options = [
157
+ '-j10' ,
158
+ '--master-host=localhost' ,
159
+ '--master-db=postgres' ,
160
+ '--master-port={0}' .format (master .port )
161
+ ]
162
+ )
163
+ # TODO: check that all ptrack are nullified
119
164
120
165
master .safe_psql ('postgres' , 'delete from t_heap where id%2 = 1' )
121
166
master .safe_psql ('postgres' , 'vacuum full t_heap' )
122
- master .safe_psql ('postgres' , 'checkpoint' )
167
+
168
+ # Sync master and replica
169
+ lsn = master .safe_psql (
170
+ 'postgres' , 'SELECT pg_catalog.pg_current_wal_lsn()' ).rstrip ()
171
+ # print(lsn)
172
+
173
+ replica .poll_query_until (
174
+ "postgres" ,
175
+ "SELECT '{0}'::pg_lsn <= pg_last_wal_replay_lsn()" .format (
176
+ lsn ))
177
+
178
+ replica .safe_psql ('postgres' , 'checkpoint' )
179
+
180
+ # print(replica.safe_psql(
181
+ # 'postgres', 'SELECT pg_catalog.pg_last_wal_replay_lsn()'))
123
182
124
183
for i in idx_ptrack :
125
184
# get new size of heap and indexes. size calculated in pages
@@ -131,7 +190,8 @@ def test_ptrack_vacuum_full_replica(self):
131
190
idx_ptrack [i ]['path' ], idx_ptrack [i ]['new_size' ])
132
191
# get ptrack for every idx
133
192
idx_ptrack [i ]['ptrack' ] = self .get_ptrack_bits_per_page_for_fork (
134
- replica , idx_ptrack [i ]['path' ], [idx_ptrack [i ]['old_size' ], idx_ptrack [i ]['new_size' ]])
193
+ replica , idx_ptrack [i ]['path' ],
194
+ [idx_ptrack [i ]['old_size' ], idx_ptrack [i ]['new_size' ]])
135
195
136
196
# compare pages and check ptrack sanity, the most important part
137
197
self .check_ptrack_sanity (idx_ptrack [i ])
0 commit comments