私は、数十のテーブルを持つ大規模なPostgreSQLデータベースを担当しています。これらのテーブルの多くは決してアクセスされないと思います。
特定のテーブルに最後にアクセスしたのがいつかを確認する最良の方法は何ですか?私は上のトリガーを追加することを考えDELETE
、INSERT
そしてUPDATE
、私は、より効率的な方法があると思います。
私は、数十のテーブルを持つ大規模なPostgreSQLデータベースを担当しています。これらのテーブルの多くは決してアクセスされないと思います。
特定のテーブルに最後にアクセスしたのがいつかを確認する最良の方法は何ですか?私は上のトリガーを追加することを考えDELETE
、INSERT
そしてUPDATE
、私は、より効率的な方法があると思います。
回答:
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)
インサート:
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)
選択:
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)
削除:
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)
update-- 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についてはわかりません。使用しています。
3番目のオプション(挿入、更新、削除アクティビティの場合)は、$ PGDATA / base / $ datidディレクトリのファイルのタイムスタンプを監視することです。ファイル名はテーブルのOIDにマップする必要があるため、これを使用して、挿入、更新、または削除を取得していないテーブルを特定できます。残念ながら、これはまだ選択されているテーブルに対応しておらず、テーブルスペースを使用するとさらに複雑になります(これらのファイルは$ PGDATA / base / $ datidの下にないため)。保留中の変更がフラッシュされるまでタイムスタンプは更新されませんが、ファイルが数か月以内に変更されていない場合、現在保留中の変更の確率はおそらく小さいです。
テーブルへの最後の変更に関するいくつかの情報をで取得できますxmin
。例:
select max(xmin::text::bigint) from t;
ただし、モジュロ、ラップアラウンド、およびフリーズされたxidに注意する必要があります。これを「時間」に変換する方法はありませんが、テーブルの値を今すぐ取得し、後で比較すると、変更されたテーブルのリストを取得できます
select
。ロギングを検討しましたか?