Alf*_*62 22 postgresql replication
我想在PostgreSQL 9.3中使用流复制来测量插入数据到master-table和slave-table之间的时间.为此,我创建了表test_time,其中包含2个字段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;
但两张桌子的时间都是一样的.我该如何测量延迟时间
dbe*_*hur 20
Alf162在对Craig Ringer的回答的评论中提到了一个很好的解决方案; 所以我加上这个来澄清.
PostgreSQL有一个管理函数pg_last_xact_replay_timestamp(),它返回恢复期间重放的最后一个事务的时间戳.这是在主数据库上生成该事务的提交或中止WAL记录的时间.
因此,select now()-pg_last_xact_replay_timestamp() as replication_lag对从属设备的此查询将返回一个持续时间,该持续时间表示当前时钟与从复制流应用的最后一个WAL记录的时间戳之间的时间差.
请注意,如果主服务器没有接收到新的突变,则不会传输WAL记录,并且以这种方式计算的延迟将增长,而实际上并不是复制延迟的信号.如果主控器或多或少存在连续突变,则它将连续地传输WAL,并且上述查询是对主设备上的更改的时间延迟的精确近似,以实现从设备上的实现.精确度显然会受到两台主机上系统时钟严格同步的影响.
Cra*_*ger 19
您可以非常轻松地从主端获取字节延迟,pg_xlog_location_diff以便将主设备pg_current_xlog_insert_location与replay_location后端的pg_stat_replication条目进行比较.
这仅适用于在主服务器上运行时.您无法从副本执行此操作,因为副本不知道主服务器的前面有多远.
此外,这不会告诉你几秒钟的滞后.在当前(至少9.4)PostgreSQL版本中,没有与提交或WAL记录相关联的时间戳.所以没有办法告诉给定的LSN(xlog位置)多久以前.
在当前PostgreSQL版本上获得副本延迟的唯一方法是让外部进程update定期提交到专用时间戳表.因此,您可以current_timestamp在副本上比较副本中可见的该表中最新条目的时间戳,以查看副本的落后程度.这会创建额外的WAL流量,然后必须将其保存在PITR(PgBarman或其他)的归档WAL中,因此您应该将增加的数据使用与您需要的滞后检测的粒度进行平衡.
PostgreSQL 9.5可能会添加提交时间戳,希望能够让您了解给定提交的持续时间,以及因此在挂钟时间内复制品的落后程度.
iur*_*niz 14
对于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;
Run Code Online (Sandbox Code Playgroud)
如果您在 master 上运行此查询,结果将是:
is_slave | receive | replay | synced | lag
----------+---------+--------+--------+-----
f | | | |
(1 row)
Run Code Online (Sandbox Code Playgroud)
如果您在同步从站上运行此查询,结果将类似于:
is_slave | receive | replay | synced | lag
----------+-----------+-----------+--------+-----
t | 0/3003128 | 0/3003128 | t | 214
(1 row)
Run Code Online (Sandbox Code Playgroud)
如果您在未同步的从属设备上运行此查询,结果将类似于:
is_slave | receive | replay | synced | lag
----------+-----------+-----------+--------+-----
t | 0/30030F0 | 0/30023B0 | f | 129
(1 row)
Run Code Online (Sandbox Code Playgroud)
注意: (seconds) 在这里有特殊含义(与//从视图中看lag不一样),并且仅当列为 时才有用,因为表示自上次操作提交以来经过了多少秒。在低流量站点中,该值是无用的。但在高流量站点中,可能(并且将会)几乎是时间,但是如果它的值足够小,则可以认为服务器已同步。replay_lagwrite_lagflush_lagpg_stat_replicationsyncedfalselagsyncedfalselag
因此,为了发现该服务器是否已同步,我检查(按此顺序):
is_slave是f(意味着不是从属设备,可能是主设备,因此它是同步的);synced是t(意味着它是同步从属设备,因此它是同步的);lag <= :threshold:(意味着不是同步从站,但它离主站不太远,所以对我来说已经足够同步了)。如果您想要以秒为单位(包括小数)的滞后,请执行以下操作:
is_slave | receive | replay | synced | lag
----------+---------+--------+--------+-----
f | | | |
(1 row)
Run Code Online (Sandbox Code Playgroud)
如果您的数据库有频繁写入,则下面的查询非常接近于获得从属延迟
select now() - pg_last_xact_replay_timestamp() AS replication_delay;
Run Code Online (Sandbox Code Playgroud)
下面是一个更精确的查询,用于计算写入次数很少的数据库的复制滞后.如果主设备没有向从设备发送任何写入,则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;
Run Code Online (Sandbox Code Playgroud)
略有不同版本的正确答案:
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
Run Code Online (Sandbox Code Playgroud)
只有当"接收"不等于"重播"时,滞后才是重要的.在slave上执行查询
截至 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 在提交时产生的延迟。
(格式化我的)
唉,新列似乎只适合同步复制(否则主不会知道确切的延迟)因此异步复制延迟 chack 似乎仍然存在now()-pg_last_xact_replay_timestamp()......