PostgreSQL, как найти любые изменения за последние n минут

Я пишу программу, которая синхронизирует базы данных сервера PostgreSQL и MS SQL (и добавляет некоторые изменения в этот переход). С несколькими миллионами записей это занимает много времени и довольно сильно загружает сервер с select *; также требуется больше ресурсов для анализа неизмененных записей и проверки их на сервере MS SQL.

Есть ли какие-либо журналы в PostgreSQL, которые я могу проанализировать, чтобы узнать об изменениях, произошедших за последние n минут? Это позволило бы мне выбирать только те записи, которые мне нужны для работы; повышение производительности.


person Andrew    schedule 07.12.2012    source источник
comment
Рассматривали ли вы xmin?   -  person    schedule 07.12.2012
comment
как я могу использовать xmin для получения измененных записей из таблицы (если в таблице 1 миллион записей?)   -  person Andrew    schedule 07.12.2012
comment
sqlfiddle.com/#!1/58507/2   -  person    schedule 07.12.2012
comment
но существенно "с большой осторожностью" - вы читали заметки о заворачивании и замороженных ксидах?   -  person    schedule 07.12.2012


Ответы (2)


Postgresql, найти изменения за последние n минут:

Postgresql не сохраняет автоматически дату или время добавления/обновления/удаления строк (обработка таких меток времени действительно замедлила бы работу, если бы вы этого не хотели).

Вам придется сделать это самостоятельно: добавить в таблицу столбец меток времени. Когда вы вставляете строку в таблицу, она обновляет столбец метки времени до current_timestamp. Когда вы выбираете строку, используйте оператор select, который отфильтровывает временную метку, превышающую N минут назад, следующим образом:

Получить строки, в которых отметка времени больше даты:

SELECT * from yourtable 
WHERE your_timestamp_field > to_date('05 Dec 2000', 'DD Mon YYYY');

Получить строки, которые были изменены за последние n минут:

SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 minutes'

Пример прохождения

drop table foo; 
CREATE TABLE foo( 
    msg character varying(20), 
    created_date date, 
    edited_date timestamp 
); 
insert into foo values( 'splog adfarm coins', '2015-01-01', current_timestamp);
insert into foo values( 'execute order 2/3', '2020-03-15', current_timestamp);
insert into foo values( 'deploy wessels', '2038-03-15', current_timestamp);
 
select * from foo where created_date < to_date('2020-05-05', 'YYYY-mm-DD'); 
    ┌────────────────────┬──────────────┬────────────────────────────┐ 
    │        msg         │ created_date │        edited_date         │ 
    ├────────────────────┼──────────────┼────────────────────────────┤ 
    │ splog adfarm coins │ 2015-01-01   │ 2020-12-29 11:46:27.968162 │ 
    │ execute order 2/3  │ 2020-03-15   │ 2020-12-29 11:46:27.96918  │ 
    └────────────────────┴──────────────┴────────────────────────────┘ 
 
select * from foo where edited_date > to_timestamp(
    '2020-12-29 11:42:37.719412', 'YYYY-MM-DD HH24_MI_SS.US'); 
    ┌────────────────────┬──────────────┬────────────────────────────┐ 
    │        msg         │ created_date │        edited_date         │ 
    ├────────────────────┼──────────────┼────────────────────────────┤ 
    │ execute order 2/3  │ 2020-03-15   │ 2020-12-29 11:46:27.96918  │ 
    │ deploy wessels     │ 2038-03-15   │ 2020-12-29 11:46:27.969988 │ 
    └────────────────────┴──────────────┴────────────────────────────┘ 
person Eric Leschinski    schedule 07.12.2012
comment
Хорошо, о вставках можно позаботиться с временными метками, а как насчет правок? - person Andrew; 07.12.2012
comment
Когда вы редактируете таблицу, вы можете либо обновить ту же временную метку, либо создать дополнительный столбец с именем date_updated и при обновлении строки пометить этот столбец как текущее время. Следите за изменениями часового пояса, переходом на летнее время и другими махинациями со временем. - person Eric Leschinski; 07.12.2012
comment
Используйте trigger для автоматического обновления поля your_timestamp_field при выполнении любой команды INSERT/UPDATE. Вам больше не нужно помнить «SET your_timestamp» во всех запросах. - person Evgeny Nozdrev; 16.10.2018

Вы можете использовать подход на основе триггера, описанный здесь:

http://wiki.postgresql.org/wiki/Audit_trigger

По сути, каждое изменение таблицы запускает триггер, который может записывать некоторую информацию в таблицу журнала.

person sega_sai    schedule 07.12.2012