PostgreSQL:上次访问表的时间

Ada*_*tan 12 postgresql

我负责一个大型 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 下)。在刷新任何挂起的更改之前时间戳不会更新,但如果文件在几个月内没有更改,那么当前挂起更改的几率可能很小。