Подтвердить что ты не робот

Как проверить задержку репликации в PostgreSQL?

Я хотел бы измерить время между вставками данных в master-table и slave-таблицу с использованием потоковой репликации в PostgreSQL 9.3. Для этого я создаю таблицу test_time с двумя полями id (serial), t (text). После этого добавлен триггер:

cur_time:=to_char(current_timestamp, 'HH12:MI:SS:MS:US'); update test_time set t=cur_time where id=new.id;

Но время одинаково в обеих таблицах. Как измерить время задержки

4b9b3361

Ответ 1

Вы можете легко получить задержку в байтах с основной стороны, используя pg_xlog_location_diff, чтобы сравнить master pg_current_xlog_insert_location с replay_location для этой записи pg_stat_replication.

Это работает только при запуске на ведущем устройстве. Вы не можете сделать это из реплики, потому что реплика не знает, насколько далеко впереди хозяин.

Кроме того, это не скажет вам отставание в секундах. В текущей (по крайней мере, версии 9.4) версии PostgreSQL нет метки времени, связанной с фиксацией или записью WAL. Таким образом, нет возможности рассказать, как давно была установлена ​​LSN (позиция xlog).

Единственный способ получить отставание реплики в секундах на текущей версии PostgreSQL - это периодически выполнять фиксацию update для отдельной таблицы временных меток. Таким образом, вы можете сравнить current_timestamp с репликой с меткой времени самой последней записи в этой таблице, видимой на реплике, чтобы увидеть, насколько отстает реплика. Это создает дополнительный WAL-трафик, который затем должен храниться в вашем архивированном WAL для PITR (PgBarman или что-то еще), поэтому вам необходимо сбалансировать расширенное использование данных с требуемой детализацией обнаружения задержки.

PostgreSQL 9.5 может добавлять метки времени фиксации, которые, мы надеемся, позволят вам узнать, как давно произошла данная фиксация, и, следовательно, насколько реплика находится за секундой в секундах.

Ответ 2

Alf162 упомянул хорошее решение в комментариях к ответу Крейга Рингера; поэтому я добавляю это, чтобы уточнить.

PostgreSQL имеет административную функцию pg_last_xact_replay_timestamp(), которая возвращает отметку времени последней транзакции, воспроизведенной во время восстановления. Это время, когда фиксация или прервать запись WAL для этой транзакции была сгенерирована на первичной.

Таким образом, этот запрос select now()-pg_last_xact_replay_timestamp() as replication_lag на подчиненном устройстве возвращает продолжительность, представляющую разность во времени между текущими часами и временной меткой последней записи WAL, применяемой в потоке репликации.

Обратите внимание, что если мастер не получает новые мутации, для потока не будет никаких записей WAL, и рассчитанное таким образом отставание будет расти, фактически не являясь сигналом задержки в репликации. Если мастер находится под более или менее непрерывной мутацией, он будет непрерывно передавать WAL, и вышеуказанный запрос является точным приближением временной задержки изменений материнской платы на подчиненном устройстве. Очевидно, что точность будет зависеть от того, насколько строго синхронизированы системные часы на двух хостах.

Ответ 3

Если в вашей базе данных есть частые записи, то приведенный ниже запрос является близким приближением, чтобы получить задержку ведомого

select now() - pg_last_xact_replay_timestamp() AS replication_delay;

Ниже приведен более точный запрос для вычисления задержки репликации для баз данных с очень небольшим количеством записей. Если мастер не отправил ни одной записи в подчиненное устройство, то pg_last_xact_replay_timestamp() может быть постоянным и, следовательно, не может точно определить задержку подчиненного устройства, используя указанный выше запрос.

SELECT CASE WHEN pg_last_xlog_receive_location() =
pg_last_xlog_replay_location() THEN 0 ELSE EXTRACT (EPOCH FROM now() -
pg_last_xact_replay_timestamp()) END AS log_delay;

Ответ 4

немного отличающаяся версия правильного ответа:

postgres=# SELECT
  pg_last_xlog_receive_location() receive,
  pg_last_xlog_replay_location() replay,
  (
   extract(epoch FROM now()) -
   extract(epoch FROM pg_last_xact_replay_timestamp())
  )::int lag;

  receive   |   replay   |  lag  
------------+------------+-------
 1/AB861728 | 1/AB861728 | 2027

отставание важно только тогда, когда "получать" не равно "повтор". выполнить запрос на ведомый

Ответ 5

начиная с версии 10:

https://www.postgresql.org/docs/10/static/monitoring-stats.html#pg-stat-replication-view

write_lag интервал Время, прошедшее между очисткой последнего WAL локально и получением уведомления о том, что этот резервный сервер имеет написал (но еще не покраснел его или применил). Это можно использовать для измерять задержку, которую синхронный_commit уровень удаленный_write понесенный при совершении, если этот сервер был настроен как синхронный в режиме ожидания.

flush_lag. Время, прошедшее между сбросом недавнего WAL локально и получением уведомления о том, что этот резервный сервер имеет написал и покраснел (но еще не применил). Это можно использовать для измерить задержку, вызванную синхронным_компьютом уровня remote_flush при совершении, если этот сервер был настроен как синхронный в режиме ожидания.

replay_lag интервал Время, прошедшее между сбросом недавнего WAL локально и получением уведомления о том, что этот резервный сервер имеет написанный, размытый и примененный. Это можно использовать для измерения задержки что synchronous_commit уровень remote_apply, понесенный при совершении если этот сервер был настроен как синхронный режим ожидания.

(форматирование шахты)

Увы, новые столбцы, похоже, подходят только для синхронной репликации (иначе мастер не знал бы точного запаздывания), таким образом, асинхронная репликация задержки chack, похоже, остается now()-pg_last_xact_replay_timestamp()...