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

Commit53b9cd2

Browse files
committed
pgstat: test stats interactions with physical replication.
Tests that standbys:- drop stats for objects when the those records are replayed- persist stats across graceful restarts- discard stats after immediate / crash restartsAuthor: Melanie Plageman <melanieplageman@gmail.com>Author: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/20220303021600.hs34ghqcw6zcokdh@alap3.anarazel.de
1 parenta90641e commit53b9cd2

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# Copyright (c) 2021-2022, PostgreSQL Global Development Group
2+
3+
# Tests that standbys:
4+
# - drop stats for objects when the those records are replayed
5+
# - persist stats across graceful restarts
6+
# - discard stats after immediate / crash restarts
7+
8+
use strict;
9+
use warnings;
10+
use PostgreSQL::Test::Cluster;
11+
use PostgreSQL::Test::Utils;
12+
use Test::More;
13+
14+
my$node_primary = PostgreSQL::Test::Cluster->new('primary');
15+
$node_primary->init(allows_streaming=> 1);
16+
$node_primary->append_conf('postgresql.conf',"track_functions = 'all'");
17+
$node_primary->start;
18+
19+
my$backup_name ='my_backup';
20+
$node_primary->backup($backup_name);
21+
22+
my$node_standby = PostgreSQL::Test::Cluster->new('standby');
23+
$node_standby->init_from_backup($node_primary,$backup_name,
24+
has_streaming=> 1);
25+
$node_standby->start;
26+
27+
28+
## Test that stats are cleaned up on standby after dropping table or function
29+
30+
my$sect ='initial';
31+
32+
my ($dboid,$tableoid,$funcoid) =
33+
populate_standby_stats('postgres','public');
34+
test_standby_func_tab_stats_status('postgres',
35+
$dboid,$tableoid,$funcoid,'t');
36+
37+
drop_table_by_oid('postgres',$tableoid);
38+
drop_function_by_oid('postgres',$funcoid);
39+
40+
$sect ='post drop';
41+
my$primary_lsn =$node_primary->lsn('flush');
42+
$node_primary->wait_for_catchup($node_standby,'replay',$primary_lsn);
43+
test_standby_func_tab_stats_status('postgres',
44+
$dboid,$tableoid,$funcoid,'f');
45+
46+
47+
## Test that stats are cleaned up on standby after dropping indirectly
48+
49+
$sect ="schema creation";
50+
51+
$node_primary->safe_psql('postgres',"CREATE SCHEMA drop_schema_test1");
52+
$primary_lsn =$node_primary->lsn('flush');
53+
$node_primary->wait_for_catchup($node_standby,'replay',$primary_lsn);
54+
55+
($dboid,$tableoid,$funcoid) =
56+
populate_standby_stats('postgres','drop_schema_test1');
57+
58+
test_standby_func_tab_stats_status('postgres',
59+
$dboid,$tableoid,$funcoid,'t');
60+
$node_primary->safe_psql('postgres',"DROP SCHEMA drop_schema_test1 CASCADE");
61+
62+
$sect ="post schema drop";
63+
64+
$primary_lsn =$node_primary->lsn('flush');
65+
$node_primary->wait_for_catchup($node_standby,'replay',$primary_lsn);
66+
67+
# verify table and function stats removed from standby
68+
test_standby_func_tab_stats_status('postgres',
69+
$dboid,$tableoid,$funcoid,'f');
70+
71+
72+
## Test that stats are cleaned up on standby after dropping database
73+
74+
$sect ="createdb";
75+
76+
$node_primary->safe_psql('postgres',"CREATE DATABASE test");
77+
$primary_lsn =$node_primary->lsn('flush');
78+
$node_primary->wait_for_catchup($node_standby,'replay',$primary_lsn);
79+
80+
($dboid,$tableoid,$funcoid) = populate_standby_stats('test','public');
81+
82+
# verify stats are present
83+
test_standby_func_tab_stats_status('test',$dboid,$tableoid,$funcoid,'t');
84+
test_standby_db_stats_status('test',$dboid,'t');
85+
86+
$node_primary->safe_psql('postgres',"DROP DATABASE test");
87+
$sect ="post dropdb";
88+
$primary_lsn =$node_primary->lsn('flush');
89+
$node_primary->wait_for_catchup($node_standby,'replay',$primary_lsn);
90+
91+
# Test that the stats were cleaned up on standby
92+
# Note that this connects to 'postgres' but provides the dboid of dropped db
93+
# 'test' which we acquired previously
94+
test_standby_func_tab_stats_status('postgres',
95+
$dboid,$tableoid,$funcoid,'f');
96+
97+
test_standby_db_stats_status('postgres',$dboid,'f');
98+
99+
100+
## verify that stats persist across graceful restarts on a replica
101+
102+
# NB: Can't test database stats, they're immediately repopulated when
103+
# reconnecting...
104+
$sect ="pre restart";
105+
($dboid,$tableoid,$funcoid) = populate_standby_stats('postgres','public');
106+
test_standby_func_tab_stats_status('postgres',
107+
$dboid,$tableoid,$funcoid,'t');
108+
109+
$node_standby->restart();
110+
111+
$sect ="post non-immediate";
112+
113+
test_standby_func_tab_stats_status('postgres',
114+
$dboid,$tableoid,$funcoid,'t');
115+
116+
# but gone after an immediate restart
117+
$node_standby->stop('immediate');
118+
$node_standby->start();
119+
120+
$sect ="post immediate restart";
121+
122+
test_standby_func_tab_stats_status('postgres',
123+
$dboid,$tableoid,$funcoid,'f');
124+
125+
126+
done_testing();
127+
128+
129+
subpopulate_standby_stats
130+
{
131+
my ($connect_db,$schema) =@_;
132+
133+
# create objects on primary
134+
$node_primary->safe_psql($connect_db,
135+
"CREATE TABLE$schema.drop_tab_test1 AS SELECT generate_series(1,100) AS a"
136+
);
137+
$node_primary->safe_psql($connect_db,
138+
"CREATE FUNCTION$schema.drop_func_test1() RETURNS VOID AS 'select 2;' LANGUAGE SQL IMMUTABLE"
139+
);
140+
my$primary_lsn =$node_primary->lsn('flush');
141+
$node_primary->wait_for_catchup($node_standby,'replay',$primary_lsn);
142+
143+
# collect object oids
144+
my$dboid =$node_standby->safe_psql($connect_db,
145+
"SELECT oid FROM pg_database WHERE datname = '$connect_db'");
146+
my$tableoid =$node_standby->safe_psql($connect_db,
147+
"SELECT '$schema.drop_tab_test1'::regclass::oid");
148+
my$funcoid =$node_standby->safe_psql($connect_db,
149+
"SELECT '$schema.drop_func_test1()'::regprocedure::oid");
150+
151+
# generate stats on standby
152+
$node_standby->safe_psql($connect_db,
153+
"SELECT * FROM$schema.drop_tab_test1");
154+
$node_standby->safe_psql($connect_db,"SELECT$schema.drop_func_test1()");
155+
156+
return ($dboid,$tableoid,$funcoid);
157+
}
158+
159+
subdrop_function_by_oid
160+
{
161+
my ($connect_db,$funcoid) =@_;
162+
163+
# Get function name from returned oid
164+
my$func_name =$node_primary->safe_psql($connect_db,
165+
"SELECT '$funcoid'::regprocedure");
166+
$node_primary->safe_psql($connect_db,"DROP FUNCTION$func_name");
167+
}
168+
169+
subdrop_table_by_oid
170+
{
171+
my ($connect_db,$tableoid) =@_;
172+
173+
# Get table name from returned oid
174+
my$table_name =
175+
$node_primary->safe_psql($connect_db,"SELECT '$tableoid'::regclass");
176+
$node_primary->safe_psql($connect_db,"DROP TABLE$table_name");
177+
}
178+
179+
subtest_standby_func_tab_stats_status
180+
{
181+
local$Test::Builder::Level =$Test::Builder::Level + 1;
182+
my ($connect_db,$dboid,$tableoid,$funcoid,$present) =@_;
183+
184+
my%expected = (rel=>$present,func=>$present);
185+
my%stats;
186+
187+
$stats{rel} =$node_standby->safe_psql($connect_db,
188+
"SELECT pg_stat_have_stats('relation',$dboid,$tableoid)");
189+
$stats{func} =$node_standby->safe_psql($connect_db,
190+
"SELECT pg_stat_have_stats('function',$dboid,$funcoid)");
191+
192+
is_deeply(\%stats, \%expected,"$sect: standby stats as expected");
193+
194+
return;
195+
}
196+
197+
subtest_standby_db_stats_status
198+
{
199+
local$Test::Builder::Level =$Test::Builder::Level + 1;
200+
my ($connect_db,$dboid,$present) =@_;
201+
202+
is($node_standby->safe_psql(
203+
$connect_db,"SELECT pg_stat_have_stats('database',$dboid, 0)"),
204+
$present,
205+
"$sect: standby db stats as expected");
206+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp