PostgreSQL: время последнего доступа к таблице

10

Я отвечаю за большую базу данных PostgreSQL с несколькими десятками таблиц. Я подозреваю, что многие из этих таблиц никогда не доступны.

Какой лучший способ проверить, когда в последний раз был доступ к определенной таблице? Я думал добавить триггер DELETE, INSERTи UPDATE, но я надеюсь, что есть более эффективный способ.

Адам Матан
источник
Вы не можете создать триггер наselect . Вы думали о регистрации ?
Джек говорит, попробуй topanswers.xyz
Спасибо, исправлено. Ведение журнала может быть решением, но БД активно используется, и журналы, вероятно, займут много места на диске.
Адам Матан

Ответы:

9

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)

обновление-- 2011-09-01

Дальнейшее тестирование показывает, что, как vacuumпредставляется, несколько увеличивает значения в pg_statio_all_tables, что нежелательно для желаемого использования. Хотя vacuumpg_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). Временные метки не будут обновляться до тех пор, пока не будут сброшены все ожидающие изменения, но если файл не изменился за месяцы, шансы ожидающих изменений в данный момент, вероятно, невелики.

gsiems
источник
3

Вы можете получить некоторую информацию о последнем изменении таблицы xmin, например:

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

Но, вы должны быть осведомлены о по модулю и опоясывающего и замороженных xids . Нет никакого способа преобразовать это в «время», но если вы сейчас захватываете значение для своих таблиц, а затем сравниваете позднее, вы можете получить список таблиц, которые изменились

Джек говорит, попробуйте topanswers.xyz
источник