PostgreSQL: Waktu akses terakhir ke tabel

10

Saya bertanggung jawab atas database PostgreSQL yang besar, dengan beberapa lusin tabel. Saya menduga bahwa banyak dari tabel ini tidak pernah diakses.

Apa cara terbaik untuk memeriksa kapan terakhir kali tabel tertentu diakses? Saya berpikir untuk menambahkan pemicu DELETE, INSERTdan UPDATE, tapi saya harap ada cara yang lebih efisien.

Adam Matan
sumber
Anda tidak dapat membuat pemicu aktifselect . Sudahkah Anda mempertimbangkan untuk masuk ?
Jack bilang coba topanswers.xyz
Terima kasih, dikoreksi. Logging mungkin solusinya, tetapi DB banyak digunakan dan log mungkin akan memakan banyak ruang disk.
Adam Matan

Jawaban:

9

pg_catalog.pg_statio_all_tables adalah teman Anda. Yang harus Anda lakukan adalah melakukan polling pg_statio_all_tables secara berkala untuk tabel yang dimaksud. Mengubah statistik ~ tabel aktif, statistik tidak berubah ~ tabel yang berpotensi tidak digunakan. Berhati-hatilah agar tidak ada yang melakukan hal select pg_stat_reset () ;di tengah pemantauan Anda.

Sebagai contoh:

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)

Sisipan:

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)

Memilih:

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)

Hapus:

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)

perbarui-- 2011-09-01

Pengujian lebih lanjut menunjukkan bahwa vacuumtampaknya meningkatkan nilai dalam pg_statio_all_tables agak, yang sangat disayangkan untuk penggunaan yang Anda inginkan. Meskipun vacuumtidak menggunakan pg_statio_all_tables tidak berguna, itu membuat menafsirkan hasil sedikit lebih fuzzier.

Mungkin tempat yang lebih baik untuk memantau adalah pg_catalog.pg_stat_all_tables (setidaknya dengan versi Pg yang lebih baru). Saya sedang melihat versi 8.4 dan yang memiliki jumlah tuple dimasukkan, dibaca, diperbarui, dan dihapus - ISTR 8.2 tidak memiliki semua itu dan saya tidak tahu tentang 8.3 jadi YMMV tergantung pada versi Pg yang Anda miliki. menggunakan.

Opsi ketiga (untuk menyisipkan, memperbarui, dan menghapus aktivitas) adalah menonton stempel waktu file di direktori $ PGDATA / base / $ datid. Nama file harus dipetakan ke oid tabel, jadi Anda bisa menggunakan ini untuk mengidentifikasi tabel yang tidak mendapatkan sisipan, pembaruan, atau penghapusan. Sayangnya, ini tidak membahas tabel yang masih dipilih, dan menggunakan tablespace akan menyebabkan komplikasi tambahan (karena file-file tersebut tidak akan di bawah $ PGDATA / base / $ datid). Stempel waktu tidak akan diperbarui hingga semua perubahan yang tertunda dihapus, tetapi jika file belum berubah dalam beberapa bulan maka kemungkinan perubahan yang saat ini tertunda mungkin kecil.

gsiems
sumber
3

Anda bisa mendapatkan beberapa informasi tentang perubahan terakhir ke tabel dengan xmin, misalnya:

select max(xmin::text::bigint) from t;

Tapi, Anda perlu mewaspadai modulo dan pembungkus dan xids beku . Tidak ada cara untuk mengubah ini menjadi "waktu", tetapi jika Anda menangkap nilai untuk tabel Anda sekarang, kemudian membandingkannya di kemudian hari, Anda bisa mendapatkan daftar tabel yang telah berubah

Jack mengatakan coba topanswers.xyz
sumber