对于postgresql 10 或更高版本(函数pg_last_xlog_receive_location() 和其他在这个版本中不存在),我使用这个:
SELECT
pg_is_in_recovery() AS is_slave,
pg_last_wal_receive_lsn() AS receive,
pg_last_wal_replay_lsn() AS replay,
pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() AS synced,
(
EXTRACT(EPOCH FROM now()) -
EXTRACT(EPOCH FROM pg_last_xact_replay_timestamp())
)::int AS lag;
如果您在 master 上运行此查询,结果将是:
is_slave | receive | replay | synced | lag
----------+---------+--------+--------+-----
f | | | |
(1 row)
如果你在同步的 slave 上运行这个查询,结果会是这样的:
is_slave | receive | replay | synced | lag
----------+-----------+-----------+--------+-----
t | 0/3003128 | 0/3003128 | t | 214
(1 row)
如果您在未同步的从站上运行此查询,结果将如下所示:
is_slave | receive | replay | synced | lag
----------+-----------+-----------+--------+-----
t | 0/30030F0 | 0/30023B0 | f | 129
(1 row)
注意:lag(秒)在这里有特殊含义(与pg_stat_replication 视图中的replay_lag/write_lag/flush_lag 不同)并且它仅在@ 时有用987654331@ 列是false,因为lag 表示自上次提交操作以来经过了多少秒。在低流量站点中,此值是无用的。但是在高流量站点中,synced 可能(并且将会)几乎是时间 false,但是如果它的 lag 值足够小,则可以认为服务器已同步。
因此,为了发现该服务器是否已同步,我检查(按此顺序):
- IF
is_slave 是f(意思是不是slave,可能是master,所以是同步的);
- IF
synced 是t(意思是同步的slave,所以是同步的);
- IF(假设适用)
lag <= :threshold:(意思是不是同步的slave,但离master不是太远,所以对我来说已经足够同步了)。
如果您想以秒为单位(包括小数),请执行以下操作:
SELECT
pg_is_in_recovery() AS is_slave,
pg_last_wal_receive_lsn() AS receive,
pg_last_wal_replay_lsn() AS replay,
pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() AS synced,
EXTRACT(SECONDS FROM now() - pg_last_xact_replay_timestamp())::float AS lag;