|
6 | 6 | fromtimeimportsleep |
7 | 7 | importshutil |
8 | 8 | importsignal |
| 9 | +fromtestgresimportProcessType |
9 | 10 |
|
10 | 11 |
|
11 | 12 | module_name='2068' |
@@ -81,25 +82,14 @@ def test_minrecpoint_on_replica(self): |
81 | 82 | stderr=subprocess.STDOUT, |
82 | 83 | options=["-c","4","-j 4","-T","100"]) |
83 | 84 |
|
84 | | -# get pids of background workers |
85 | | -startup_pid=replica.safe_psql( |
86 | | -'postgres', |
87 | | -"select pid from pg_stat_activity " |
88 | | -"where backend_type = 'startup'").rstrip() |
89 | | - |
90 | | -checkpointer_pid=replica.safe_psql( |
91 | | -'postgres', |
92 | | -"select pid from pg_stat_activity " |
93 | | -"where backend_type = 'checkpointer'").rstrip() |
94 | | - |
95 | | -bgwriter_pid=replica.safe_psql( |
96 | | -'postgres', |
97 | | -"select pid from pg_stat_activity " |
98 | | -"where backend_type = 'background writer'").rstrip() |
99 | | - |
100 | 85 | # wait for shared buffer on replica to be filled with dirty data |
101 | 86 | sleep(10) |
102 | 87 |
|
| 88 | +# get pids of replica background workers |
| 89 | +startup_pid=replica.auxiliary_pids[ProcessType.Startup][0] |
| 90 | +checkpointer_pid=replica.auxiliary_pids[ProcessType.Checkpointer][0] |
| 91 | +bgwriter_pid=replica.auxiliary_pids[ProcessType.BackgroundWriter][0] |
| 92 | + |
103 | 93 | # break checkpointer on UpdateLastRemovedPtr |
104 | 94 | gdb_checkpointer=self.gdb_attach(checkpointer_pid) |
105 | 95 | gdb_checkpointer._execute('handle SIGINT noprint nostop pass') |
@@ -138,7 +128,29 @@ def test_minrecpoint_on_replica(self): |
138 | 128 | 'recovery.conf',"recovery_target_action = 'promote'") |
139 | 129 | replica.slow_start() |
140 | 130 |
|
141 | | -script=''' |
| 131 | +ifself.get_version(node)<100000: |
| 132 | +script=''' |
| 133 | +DO |
| 134 | +$$ |
| 135 | +relations = plpy.execute("select class.oid from pg_class class WHERE class.relkind IN ('r', 'i', 't', 'm') and class.relpersistence = 'p'") |
| 136 | +current_xlog_lsn = plpy.execute("select pg_last_xlog_replay_location() as lsn")[0]['lsn'] |
| 137 | +plpy.notice('CURRENT LSN: {0}'.format(current_xlog_lsn)) |
| 138 | +found_corruption = False |
| 139 | +for relation in relations: |
| 140 | + pages_from_future = plpy.execute("with number_of_blocks as (select blknum from generate_series(0, pg_relation_size({0}) / 8192 -1) as blknum) select blknum, lsn, checksum, flags, lower, upper, special, pagesize, version, prune_xid from number_of_blocks, page_header(get_raw_page('{0}'::oid::regclass::text, number_of_blocks.blknum::int)) where lsn > '{1}'::pg_lsn".format(relation['oid'], current_xlog_lsn)) |
| 141 | +
|
| 142 | + if pages_from_future.nrows() == 0: |
| 143 | + continue |
| 144 | +
|
| 145 | + for page in pages_from_future: |
| 146 | + plpy.notice('Found page from future. OID: {0}, BLKNUM: {1}, LSN: {2}'.format(relation['oid'], page['blknum'], page['lsn'])) |
| 147 | + found_corruption = True |
| 148 | +if found_corruption: |
| 149 | + plpy.error('Found Corruption') |
| 150 | +$$ LANGUAGE plpythonu; |
| 151 | +''' |
| 152 | +else: |
| 153 | +script=''' |
142 | 154 | DO |
143 | 155 | $$ |
144 | 156 | relations = plpy.execute("select class.oid from pg_class class WHERE class.relkind IN ('r', 'i', 't', 'm') and class.relpersistence = 'p'") |
|