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

Commit62af177

Browse files
anarazelpull[bot]
authored andcommitted
Add tests for pg_stat_io
Author: Melanie Plageman <melanieplageman@gmail.com>Reviewed-by: Andres Freund <andres@anarazel.de>Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>Discussion:https://postgr.es/m/20200124195226.lth52iydq2n2uilq@alap3.anarazel.de
1 parent0067c07 commit62af177

File tree

4 files changed

+431
-0
lines changed

4 files changed

+431
-0
lines changed

‎contrib/amcheck/expected/check_heap.out

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,22 @@ SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-VISIBLE');
6666
INSERT INTO heaptest (a, b)
6767
(SELECT gs, repeat('x', gs)
6868
FROM generate_series(1,50) gs);
69+
-- pg_stat_io test:
70+
-- verify_heapam always uses a BAS_BULKREAD BufferAccessStrategy, whereas a
71+
-- sequential scan does so only if the table is large enough when compared to
72+
-- shared buffers (see initscan()). CREATE DATABASE ... also unconditionally
73+
-- uses a BAS_BULKREAD strategy, but we have chosen to use a tablespace and
74+
-- verify_heapam to provide coverage instead of adding another expensive
75+
-- operation to the main regression test suite.
76+
--
77+
-- Create an alternative tablespace and move the heaptest table to it, causing
78+
-- it to be rewritten and all the blocks to reliably evicted from shared
79+
-- buffers -- guaranteeing actual reads when we next select from it.
80+
SET allow_in_place_tablespaces = true;
81+
CREATE TABLESPACE regress_test_stats_tblspc LOCATION '';
82+
SELECT sum(reads) AS stats_bulkreads_before
83+
FROM pg_stat_io WHERE io_context = 'bulkread' \gset
84+
ALTER TABLE heaptest SET TABLESPACE regress_test_stats_tblspc;
6985
-- Check that valid options are not rejected nor corruption reported
7086
-- for a non-empty table
7187
SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none');
@@ -88,6 +104,23 @@ SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock :=
88104
-------+--------+--------+-----
89105
(0 rows)
90106

107+
-- verify_heapam should have read in the page written out by
108+
-- ALTER TABLE ... SET TABLESPACE ...
109+
-- causing an additional bulkread, which should be reflected in pg_stat_io.
110+
SELECT pg_stat_force_next_flush();
111+
pg_stat_force_next_flush
112+
--------------------------
113+
114+
(1 row)
115+
116+
SELECT sum(reads) AS stats_bulkreads_after
117+
FROM pg_stat_io WHERE io_context = 'bulkread' \gset
118+
SELECT :stats_bulkreads_after > :stats_bulkreads_before;
119+
?column?
120+
----------
121+
t
122+
(1 row)
123+
91124
CREATE ROLE regress_heaptest_role;
92125
-- verify permissions are checked (error due to function not callable)
93126
SET ROLE regress_heaptest_role;
@@ -195,6 +228,7 @@ ERROR: cannot check relation "test_foreign_table"
195228
DETAIL: This operation is not supported for foreign tables.
196229
-- cleanup
197230
DROP TABLE heaptest;
231+
DROP TABLESPACE regress_test_stats_tblspc;
198232
DROP TABLE test_partition;
199233
DROP TABLE test_partitioned;
200234
DROP OWNED BY regress_heaptest_role; -- permissions

‎contrib/amcheck/sql/check_heap.sql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,44 @@ SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'NONE');
2020
SELECT*FROM verify_heapam(relation :='heaptest', skip :='ALL-FROZEN');
2121
SELECT*FROM verify_heapam(relation :='heaptest', skip :='ALL-VISIBLE');
2222

23+
2324
-- Add some data so subsequent tests are not entirely trivial
2425
INSERT INTO heaptest (a, b)
2526
(SELECT gs, repeat('x', gs)
2627
FROM generate_series(1,50) gs);
2728

29+
-- pg_stat_io test:
30+
-- verify_heapam always uses a BAS_BULKREAD BufferAccessStrategy, whereas a
31+
-- sequential scan does so only if the table is large enough when compared to
32+
-- shared buffers (see initscan()). CREATE DATABASE ... also unconditionally
33+
-- uses a BAS_BULKREAD strategy, but we have chosen to use a tablespace and
34+
-- verify_heapam to provide coverage instead of adding another expensive
35+
-- operation to the main regression test suite.
36+
--
37+
-- Create an alternative tablespace and move the heaptest table to it, causing
38+
-- it to be rewritten and all the blocks to reliably evicted from shared
39+
-- buffers -- guaranteeing actual reads when we next select from it.
40+
SET allow_in_place_tablespaces= true;
41+
CREATETABLESPACEregress_test_stats_tblspc LOCATION'';
42+
SELECTsum(reads)AS stats_bulkreads_before
43+
FROM pg_stat_ioWHERE io_context='bulkread' \gset
44+
ALTERTABLE heaptestSET TABLESPACE regress_test_stats_tblspc;
45+
2846
-- Check that valid options are not rejected nor corruption reported
2947
-- for a non-empty table
3048
SELECT*FROM verify_heapam(relation :='heaptest', skip :='none');
3149
SELECT*FROM verify_heapam(relation :='heaptest', skip :='all-frozen');
3250
SELECT*FROM verify_heapam(relation :='heaptest', skip :='all-visible');
3351
SELECT*FROM verify_heapam(relation :='heaptest', startblock :=0, endblock :=0);
3452

53+
-- verify_heapam should have read in the page written out by
54+
-- ALTER TABLE ... SET TABLESPACE ...
55+
-- causing an additional bulkread, which should be reflected in pg_stat_io.
56+
SELECT pg_stat_force_next_flush();
57+
SELECTsum(reads)AS stats_bulkreads_after
58+
FROM pg_stat_ioWHERE io_context='bulkread' \gset
59+
SELECT :stats_bulkreads_after> :stats_bulkreads_before;
60+
3561
CREATE ROLE regress_heaptest_role;
3662

3763
-- verify permissions are checked (error due to function not callable)
@@ -110,6 +136,7 @@ SELECT * FROM verify_heapam('test_foreign_table',
110136

111137
-- cleanup
112138
DROPTABLE heaptest;
139+
DROPTABLESPACE regress_test_stats_tblspc;
113140
DROPTABLE test_partition;
114141
DROPTABLE test_partitioned;
115142
DROP OWNED BY regress_heaptest_role;-- permissions

‎src/test/regress/expected/stats.out

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,4 +1126,232 @@ SELECT pg_stat_get_subscription_stats(NULL);
11261126

11271127
(1 row)
11281128

1129+
-- Test that the following operations are tracked in pg_stat_io:
1130+
-- - reads of target blocks into shared buffers
1131+
-- - writes of shared buffers to permanent storage
1132+
-- - extends of relations using shared buffers
1133+
-- - fsyncs done to ensure the durability of data dirtying shared buffers
1134+
-- There is no test for blocks evicted from shared buffers, because we cannot
1135+
-- be sure of the state of shared buffers at the point the test is run.
1136+
-- Create a regular table and insert some data to generate IOCONTEXT_NORMAL
1137+
-- extends.
1138+
SELECT sum(extends) AS io_sum_shared_before_extends
1139+
FROM pg_stat_io WHERE io_context = 'normal' AND io_object = 'relation' \gset
1140+
CREATE TABLE test_io_shared(a int);
1141+
INSERT INTO test_io_shared SELECT i FROM generate_series(1,100)i;
1142+
SELECT pg_stat_force_next_flush();
1143+
pg_stat_force_next_flush
1144+
--------------------------
1145+
1146+
(1 row)
1147+
1148+
SELECT sum(extends) AS io_sum_shared_after_extends
1149+
FROM pg_stat_io WHERE io_context = 'normal' AND io_object = 'relation' \gset
1150+
SELECT :io_sum_shared_after_extends > :io_sum_shared_before_extends;
1151+
?column?
1152+
----------
1153+
t
1154+
(1 row)
1155+
1156+
-- After a checkpoint, there should be some additional IOCONTEXT_NORMAL writes
1157+
-- and fsyncs.
1158+
SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs
1159+
FROM pg_stat_io
1160+
WHERE io_context = 'normal' AND io_object = 'relation' \gset io_sum_shared_before_
1161+
-- See comment above for rationale for two explicit CHECKPOINTs.
1162+
CHECKPOINT;
1163+
CHECKPOINT;
1164+
SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs
1165+
FROM pg_stat_io
1166+
WHERE io_context = 'normal' AND io_object = 'relation' \gset io_sum_shared_after_
1167+
SELECT :io_sum_shared_after_writes > :io_sum_shared_before_writes;
1168+
?column?
1169+
----------
1170+
t
1171+
(1 row)
1172+
1173+
SELECT current_setting('fsync') = 'off'
1174+
OR :io_sum_shared_after_fsyncs > :io_sum_shared_before_fsyncs;
1175+
?column?
1176+
----------
1177+
t
1178+
(1 row)
1179+
1180+
-- Change the tablespace so that the table is rewritten directly, then SELECT
1181+
-- from it to cause it to be read back into shared buffers.
1182+
SELECT sum(reads) AS io_sum_shared_before_reads
1183+
FROM pg_stat_io WHERE io_context = 'normal' AND io_object = 'relation' \gset
1184+
ALTER TABLE test_io_shared SET TABLESPACE regress_tblspace;
1185+
-- SELECT from the table so that the data is read into shared buffers and
1186+
-- io_context 'normal', io_object 'relation' reads are counted.
1187+
SELECT COUNT(*) FROM test_io_shared;
1188+
count
1189+
-------
1190+
100
1191+
(1 row)
1192+
1193+
SELECT pg_stat_force_next_flush();
1194+
pg_stat_force_next_flush
1195+
--------------------------
1196+
1197+
(1 row)
1198+
1199+
SELECT sum(reads) AS io_sum_shared_after_reads
1200+
FROM pg_stat_io WHERE io_context = 'normal' AND io_object = 'relation' \gset
1201+
SELECT :io_sum_shared_after_reads > :io_sum_shared_before_reads;
1202+
?column?
1203+
----------
1204+
t
1205+
(1 row)
1206+
1207+
DROP TABLE test_io_shared;
1208+
-- Test that the follow IOCONTEXT_LOCAL IOOps are tracked in pg_stat_io:
1209+
-- - eviction of local buffers in order to reuse them
1210+
-- - reads of temporary table blocks into local buffers
1211+
-- - writes of local buffers to permanent storage
1212+
-- - extends of temporary tables
1213+
-- Set temp_buffers to its minimum so that we can trigger writes with fewer
1214+
-- inserted tuples. Do so in a new session in case temporary tables have been
1215+
-- accessed by previous tests in this session.
1216+
\c
1217+
SET temp_buffers TO 100;
1218+
CREATE TEMPORARY TABLE test_io_local(a int, b TEXT);
1219+
SELECT sum(extends) AS extends, sum(evictions) AS evictions, sum(writes) AS writes
1220+
FROM pg_stat_io
1221+
WHERE io_context = 'normal' AND io_object = 'temp relation' \gset io_sum_local_before_
1222+
-- Insert tuples into the temporary table, generating extends in the stats.
1223+
-- Insert enough values that we need to reuse and write out dirty local
1224+
-- buffers, generating evictions and writes.
1225+
INSERT INTO test_io_local SELECT generate_series(1, 5000) as id, repeat('a', 200);
1226+
-- Ensure the table is large enough to exceed our temp_buffers setting.
1227+
SELECT pg_relation_size('test_io_local') / current_setting('block_size')::int8 > 100;
1228+
?column?
1229+
----------
1230+
t
1231+
(1 row)
1232+
1233+
SELECT sum(reads) AS io_sum_local_before_reads
1234+
FROM pg_stat_io WHERE io_context = 'normal' AND io_object = 'temp relation' \gset
1235+
-- Read in evicted buffers, generating reads.
1236+
SELECT COUNT(*) FROM test_io_local;
1237+
count
1238+
-------
1239+
5000
1240+
(1 row)
1241+
1242+
SELECT pg_stat_force_next_flush();
1243+
pg_stat_force_next_flush
1244+
--------------------------
1245+
1246+
(1 row)
1247+
1248+
SELECT sum(evictions) AS evictions,
1249+
sum(reads) AS reads,
1250+
sum(writes) AS writes,
1251+
sum(extends) AS extends
1252+
FROM pg_stat_io
1253+
WHERE io_context = 'normal' AND io_object = 'temp relation' \gset io_sum_local_after_
1254+
SELECT :io_sum_local_after_evictions > :io_sum_local_before_evictions,
1255+
:io_sum_local_after_reads > :io_sum_local_before_reads,
1256+
:io_sum_local_after_writes > :io_sum_local_before_writes,
1257+
:io_sum_local_after_extends > :io_sum_local_before_extends;
1258+
?column? | ?column? | ?column? | ?column?
1259+
----------+----------+----------+----------
1260+
t | t | t | t
1261+
(1 row)
1262+
1263+
-- Change the tablespaces so that the temporary table is rewritten to other
1264+
-- local buffers, exercising a different codepath than standard local buffer
1265+
-- writes.
1266+
ALTER TABLE test_io_local SET TABLESPACE regress_tblspace;
1267+
SELECT pg_stat_force_next_flush();
1268+
pg_stat_force_next_flush
1269+
--------------------------
1270+
1271+
(1 row)
1272+
1273+
SELECT sum(writes) AS io_sum_local_new_tblspc_writes
1274+
FROM pg_stat_io WHERE io_context = 'normal' AND io_object = 'temp relation' \gset
1275+
SELECT :io_sum_local_new_tblspc_writes > :io_sum_local_after_writes;
1276+
?column?
1277+
----------
1278+
t
1279+
(1 row)
1280+
1281+
RESET temp_buffers;
1282+
-- Test that reuse of strategy buffers and reads of blocks into these reused
1283+
-- buffers while VACUUMing are tracked in pg_stat_io.
1284+
-- Set wal_skip_threshold smaller than the expected size of
1285+
-- test_io_vac_strategy so that, even if wal_level is minimal, VACUUM FULL will
1286+
-- fsync the newly rewritten test_io_vac_strategy instead of writing it to WAL.
1287+
-- Writing it to WAL will result in the newly written relation pages being in
1288+
-- shared buffers -- preventing us from testing BAS_VACUUM BufferAccessStrategy
1289+
-- reads.
1290+
SET wal_skip_threshold = '1 kB';
1291+
SELECT sum(reuses) AS reuses, sum(reads) AS reads
1292+
FROM pg_stat_io WHERE io_context = 'vacuum' \gset io_sum_vac_strategy_before_
1293+
CREATE TABLE test_io_vac_strategy(a int, b int) WITH (autovacuum_enabled = 'false');
1294+
INSERT INTO test_io_vac_strategy SELECT i, i from generate_series(1, 8000)i;
1295+
-- Ensure that the next VACUUM will need to perform IO by rewriting the table
1296+
-- first with VACUUM (FULL).
1297+
VACUUM (FULL) test_io_vac_strategy;
1298+
VACUUM (PARALLEL 0) test_io_vac_strategy;
1299+
SELECT pg_stat_force_next_flush();
1300+
pg_stat_force_next_flush
1301+
--------------------------
1302+
1303+
(1 row)
1304+
1305+
SELECT sum(reuses) AS reuses, sum(reads) AS reads
1306+
FROM pg_stat_io WHERE io_context = 'vacuum' \gset io_sum_vac_strategy_after_
1307+
SELECT :io_sum_vac_strategy_after_reads > :io_sum_vac_strategy_before_reads,
1308+
:io_sum_vac_strategy_after_reuses > :io_sum_vac_strategy_before_reuses;
1309+
?column? | ?column?
1310+
----------+----------
1311+
t | t
1312+
(1 row)
1313+
1314+
RESET wal_skip_threshold;
1315+
-- Test that extends done by a CTAS, which uses a BAS_BULKWRITE
1316+
-- BufferAccessStrategy, are tracked in pg_stat_io.
1317+
SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_before
1318+
FROM pg_stat_io WHERE io_context = 'bulkwrite' \gset
1319+
CREATE TABLE test_io_bulkwrite_strategy AS SELECT i FROM generate_series(1,100)i;
1320+
SELECT pg_stat_force_next_flush();
1321+
pg_stat_force_next_flush
1322+
--------------------------
1323+
1324+
(1 row)
1325+
1326+
SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_after
1327+
FROM pg_stat_io WHERE io_context = 'bulkwrite' \gset
1328+
SELECT :io_sum_bulkwrite_strategy_extends_after > :io_sum_bulkwrite_strategy_extends_before;
1329+
?column?
1330+
----------
1331+
t
1332+
(1 row)
1333+
1334+
-- Test IO stats reset
1335+
SELECT pg_stat_have_stats('io', 0, 0);
1336+
pg_stat_have_stats
1337+
--------------------
1338+
t
1339+
(1 row)
1340+
1341+
SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) AS io_stats_pre_reset
1342+
FROM pg_stat_io \gset
1343+
SELECT pg_stat_reset_shared('io');
1344+
pg_stat_reset_shared
1345+
----------------------
1346+
1347+
(1 row)
1348+
1349+
SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) AS io_stats_post_reset
1350+
FROM pg_stat_io \gset
1351+
SELECT :io_stats_post_reset < :io_stats_pre_reset;
1352+
?column?
1353+
----------
1354+
t
1355+
(1 row)
1356+
11291357
-- End of Stats Test

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp