由 John Doe 四月 16, 2025
你想不想知道 PostgreSQL 在每个表上面,进行清理和分析所花费的时间?现在,PostgreSQL 提供了清理和分析关系表的累积统计信息。
特性提交日志
跟踪每个表在 [自动] 清理和 [自动] 分析中累计花费的时间。
本次提交在表关系的统计信息中新增了四个字段,用于汇总对每个表关系执行各项操作所花费的时间:
total_vacuum_time
,用于记录手动清理操作所花费的时间。total_autovacuum_time
,用于记录自动清理守护进程执行清理操作所花费的时间。total_analyze_time
,用于记录手动分析操作所花费的时间。total_autoanalyze_time
,用于记录自动清理守护进程执行分析操作所花费的时间。
借助相关的 “计数” 字段,用户可以利用这些新增字段计算出执行这些操作的平均耗时。
讨论:https://postgr.es/m/CAA5RZ0uVOGBYmPEeGF2d1B_67tgNjKx_bKDuL+oUftuoz+=Y1g@mail.gmail.com
示例
PostgreSQL 的统计系统几乎在每次版本发布时都会增加更多详细信息,PostgreSQL 18 也不例外。
在 PostgreSQL 17 中查看pg_stat_all_tables
(或pg_stat_user_tables
)时,它是这样的:
postgres=# select version();
version
-----------------------------------------------------------------------------------------------------------------------------
PostgreSQL 17.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.2.1 20250110 (Red Hat 14.2.1-7), 64-bit
(1 row)
postgres=# \d pg_stat_all_tables
View "pg_catalog.pg_stat_all_tables"
Column | Type | Collation | Nullable | Default
---------------------+--------------------------+-----------+----------+---------
relid | oid | | |
schemaname | name | | |
relname | name | | |
seq_scan | bigint | | |
last_seq_scan | timestamp with time zone | | |
seq_tup_read | bigint | | |
idx_scan | bigint | | |
last_idx_scan | timestamp with time zone | | |
idx_tup_fetch | bigint | | |
n_tup_ins | bigint | | |
n_tup_upd | bigint | | |
n_tup_del | bigint | | |
n_tup_hot_upd | bigint | | |
n_tup_newpage_upd | bigint | | |
n_live_tup | bigint | | |
n_dead_tup | bigint | | |
n_mod_since_analyze | bigint | | |
n_ins_since_vacuum | bigint | | |
last_vacuum | timestamp with time zone | | |
last_autovacuum | timestamp with time zone | | |
last_analyze | timestamp with time zone | | |
last_autoanalyze | timestamp with time zone | | |
vacuum_count | bigint | | |
autovacuum_count | bigint | | |
analyze_count | bigint | | |
autoanalyze_count | bigint | | |
其中已经包含了 [自动] 清理和 [自动] 分析的统计信息,但没有关于系统在清理和分析操作上总共花费了多少时间的信息。现在,这个信息可以获取到了:
postgres=# select version();
version
--------------------------------------------------------------------
PostgreSQL 18devel on x86_64-linux, compiled by gcc-14.2.1, 64-bit
(1 row)
postgres=# \d pg_stat_all_tables
View "pg_catalog.pg_stat_all_tables"
Column | Type | Collation | Nullable | Default
------------------------+--------------------------+-----------+----------+---------
relid | oid | | |
schemaname | name | | |
relname | name | | |
seq_scan | bigint | | |
last_seq_scan | timestamp with time zone | | |
seq_tup_read | bigint | | |
idx_scan | bigint | | |
last_idx_scan | timestamp with time zone | | |
idx_tup_fetch | bigint | | |
n_tup_ins | bigint | | |
n_tup_upd | bigint | | |
n_tup_del | bigint | | |
n_tup_hot_upd | bigint | | |
n_tup_newpage_upd | bigint | | |
n_live_tup | bigint | | |
n_dead_tup | bigint | | |
n_mod_since_analyze | bigint | | |
n_ins_since_vacuum | bigint | | |
last_vacuum | timestamp with time zone | | |
last_autovacuum | timestamp with time zone | | |
last_analyze | timestamp with time zone | | |
last_autoanalyze | timestamp with time zone | | |
vacuum_count | bigint | | |
autovacuum_count | bigint | | |
analyze_count | bigint | | |
autoanalyze_count | bigint | | |
total_vacuum_time | double precision | | |
total_autovacuum_time | double precision | | |
total_analyze_time | double precision | | |
total_autoanalyze_time | double precision | | |
为了实际查看这些信息,我们创建一个小表并插入数据:
create table t ( a int, b text);
insert into t select i, i::text from generate_series(1,1000000) i;
这会触发自动清理(由于autovacuum_naptime
参数的设置,你可能需要等待长达一分钟才能看到结果),你可以获取到自动清理和自动分析所花费的总时间(以毫秒为单位):
select last_autovacuum
, last_autoanalyze
, total_autovacuum_time
, total_autoanalyze_time
from pg_stat_all_tables
where relname = 't';
last_autovacuum | last_autoanalyze | total_autovacuum_time | total_autoanalyze_time
-------------------------------+-------------------------------+-----------------------+------------------------
2025-04-12 11:12:09.809252+08 | 2025-04-12 11:12:09.942748+08 | 187 | 134
(1 row)
如果你手动触发清理或分析操作,也会出现同样的情况:
select last_vacuum
, last_analyze
, total_vacuum_time
, total_analyze_time
from pg_stat_all_tables
where relname = 't';
last_vacuum | last_analyze | total_vacuum_time | total_analyze_time
-------------+--------------+-------------------+--------------------
| | 0 | 0
(1 row)
analyze t;
select last_vacuum
, last_analyze
, total_vacuum_time
, total_analyze_time
from pg_stat_all_tables
where relname = 't';
last_vacuum | last_analyze | total_vacuum_time | total_analyze_time
-------------+-------------------------------+-------------------+--------------------
| 2025-04-12 11:23:07.102182+08 | 0 | 52
(1 row)
vacuum t;
select last_vacuum
, last_analyze
, total_vacuum_time
, total_analyze_time
from pg_stat_all_tables
where relname = 't';
last_vacuum | last_analyze | total_vacuum_time | total_analyze_time
-------------------------------+-------------------------------+-------------------+--------------------
2025-04-12 11:23:12.286613+08 | 2025-04-12 11:23:07.102182+08 | 1 | 52
这非常有助于确定 [自动] 清理和 [自动] 分析花费时间最多的那些表关系。
非常不错的体验。感谢社区的所有相关人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/30a6ed0ce4bb18212ec38cdb537ea4b43bc99b83