我负责一个大型 PostgreSQL 数据库,有几十个表。我怀疑其中许多表从未被访问过。
检查上次访问某个表是什么时候的最佳方法是什么?我想在DELETE
,INSERT
和上添加触发器UPDATE
,但我希望有更有效的方法。
gsi*_*ems 11
pg_catalog.pg_statio_all_tables是你的朋友。您需要做的就是定期轮询 pg_statio_all_tables 以获得相关表。更改统计数据 ~ 活动表,不变统计数据 ~ 可能未使用的表。请注意,没有人select pg_stat_reset () ;
在您的监控过程中执行任何操作。
例如:
test_1=# create table test_stats (col1 integer);
CREATE TABLE
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 0 | 0 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
Run Code Online (Sandbox Code Playgroud)
插入:
test_1=# insert into test_stats (col1) select generate_series( 1, 10000000);
INSERT 0 10000000
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 44260 | 10088481 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
Run Code Online (Sandbox Code Playgroud)
选择:
test_1=# select count (*) from test_stats where col1 between 10000 and 50000;
count
-------
40001
(1 row)
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 85560 | 10091429 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
Run Code Online (Sandbox Code Playgroud)
删除:
test_1=# delete from test_stats where col1 between 10000 and 50000;
DELETE 40001
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 155075 | 10136163 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
Run Code Online (Sandbox Code Playgroud)
更新-- 2011-09-01
进一步的测试表明,这vacuum
似乎会增加 pg_statio_all_tables 中的值,这对于您想要的用途来说是不幸的。虽然vacuum
没有使用 pg_statio_all_tables 无用,但它确实使解释结果有点模糊。
也许更好的监控位置是 pg_catalog.pg_stat_all_tables(至少对于较新版本的 Pg)。我正在查看 8.4 版,它对插入、读取、更新和删除的元组进行计数——ISTR 8.2 没有所有这些,我不知道 8.3,所以 YMMV 取决于您使用的 Pg 版本使用。
第三个选项(用于插入、更新和删除活动)是查看 $PGDATA/base/$datid 目录中的文件时间戳。文件名应映射到表的 oid,因此您可以使用它来标识未进行插入、更新或删除的表。不幸的是,这并没有解决仍在从中选择的表,并且使用表空间会导致额外的复杂性(因为这些文件不会在 $PGDATA/base/$datid 下)。在刷新任何挂起的更改之前时间戳不会更新,但如果文件在几个月内没有更改,那么当前挂起更改的几率可能很小。