cur_time:=to_char(current_timestamp, 'HH12:MI:SS:MS:US');
update test_time set t=cur_time where id=new.id;
但两个表中的时间是相同的。我该如何测量延迟时间?
cur_time:=to_char(current_timestamp, 'HH12:MI:SS:MS:US');
update test_time set t=cur_time where id=new.id;
但两个表中的时间是相同的。我该如何测量延迟时间?
Alf162在Craig Ringer的回答评论中提到了一个好的解决方案,所以我在这里进行澄清。
PostgreSQL有一个管理函数pg_last_xact_replay_timestamp(),它返回恢复期间重放的最后一个事务的时间戳。 这是主服务器上为该事务生成提交或中止WAL记录的时间。
因此,在副本上执行此查询select now()-pg_last_xact_replay_timestamp() as replication_lag
将返回一个持续时间,表示当前时钟与从复制流应用的最后一个WAL记录的时间戳之间的时间差异。
请注意,如果主服务器未接收新的变更,则没有要流式传输的WAL记录,并且通过此方式计算的延迟将增长,而不会实际信号化复制延迟。如果主服务器几乎持续处于变更状态,它将不断流式传输WAL,并且上述查询是主服务器上更改出现在从服务器上的时间延迟的良好近似值。显然,系统时钟在两个主机上如何同步会影响准确性。
sent_lsn
、replay_lsn
和 write_lsn
是一个更好的选择。在 PG 的上下文中,时间的概念并不存在。 - vinni_fpg_xlog_location_diff
比较主服务器的pg_current_xlog_insert_location
和该后端的pg_stat_replication
条目的replay_location
,从而很容易地从主服务器端获取以字节为单位的延迟。update
的外部进程。因此,您可以将副本上的current_timestamp
与在副本上可见的最新条目的时间戳进行比较,以查看副本落后多少。这将创建额外的WAL流量,然后必须将其保留在您的归档WAL中以进行PITR(例如PgBarman),因此您应该平衡所需的滞后检测的粒度和增加的数据使用情况。pg_stat_replication
视图现在包含副本滞后时间(write_lag、flush_lag、replay_lag):请参见 Vao 的答案:https://dev59.com/ZV4c5IYBdhLWcg3wFm84#46662612 - erwaman如果您的数据库频繁进行写操作,那么下面的查询是一个接近获取从库滞后的近似值的方法。
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;
对于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;
如果在主节点上运行此查询,则结果将如下所示:
is_slave | receive | replay | synced | lag
----------+---------+--------+--------+-----
f | | | |
(1 row)
如果你在同步从库上运行此查询,结果将如下:
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
不同),它仅在synced
列为false
时才有用,因为lag
表示自上次操作提交以来经过了多少秒。 在低流量的网站中,此值是无用的。 但是在高流量的网站中,synced
几乎总是false
,但是如果它具有足够小的lag
值,则可以认为该服务器已同步。
因此,为了发现该服务器是否已同步,我按以下顺序检查:
is_slave
是f
(表示不是从属服务器,可能是主服务器,因此已同步);synced
是t
(表示已同步的从属服务器,因此已同步);lag <= :threshold:
(表示不是已同步的从属服务器,但距离主服务器不太远,因此对我来说已获得同步状态)。如果您想要包括小数秒的延迟,请执行以下操作:
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;
稍微不同的正确答案版本:
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
当“接收”不等于“回复”时,延迟只有很重要。在副本上执行查询。
截至10版:
https://www.postgresql.org/docs/10/static/monitoring-stats.html#pg-stat-replication-view
write_lag 间隔时间 本地刷新最近的WAL并接收到此备用服务器已写入但尚未刷新或应用的通知之间经过的时间。如果此服务器被配置为同步备用,则可以使用此项来衡量在提交时synchronous_commit级别remote_write所引起的延迟。
flush_lag 间隔时间 本地刷新最近的WAL并接收到此备用服务器已写入和刷新但尚未应用的通知之间经过的时间。如果此服务器被配置为同步备用,则可以使用此项来衡量在提交时synchronous_commit级别remote_flush所引起的延迟。
replay_lag 间隔时间 本地刷新最近的WAL并接收到此备用服务器已写入、刷新和应用的通知之间经过的时间。如果此服务器被配置为同步备用,则可以使用此项来衡量在提交时synchronous_commit级别remote_apply所引起的延迟。
(格式由我调整)
不幸的是,新列似乎只适用于同步复制(否则主服务器将不知道确切的延迟),因此异步复制延迟检查似乎仍为now()-pg_last_xact_replay_timestamp()
...
您可以使用这个简单的基于CLI的开源工具,它可以提供实时可视化关于复制延迟的信息,使用各种模式,例如CLI、Web模式以及基于Matplotlib的图表,方便跟踪。
欢迎提出任何问题或为其做出贡献。
select * from pg_stat_replication;
这将给您以下结果:| sent_lsn | write_lsn | flush_lsn | replay_lsn
-+-------------+-------------+-------------+-------------
| 8D/2DA48000 | 8D/2DA48000 | 8D/2DA48000 | 89/56A0D500
这些可以告诉您偏移量的位置。正如您从此示例中看到的那样,副本上的回放落后了。