Skip to content

Commit 12cf2a2

Browse files
author
xiongcc
committed
添加第17章:How to determine the replication lag
1 parent 0ac5d1c commit 12cf2a2

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# How to determine the replication lag
2+
3+
> 我每天都会发布一篇新的 PostgreSQL "howto" 文章。加入我的旅程吧 — 订阅、提供反馈、分享!
4+
5+
## 在主节点/备节点领导节点上
6+
7+
当连接到主节点 (或级联复制情况下的备节点的领导节点) 时,你可以使用 `pg_stat_replication`
8+
9+
```sql
10+
nik=# \d pg_stat_replication
11+
View "pg_catalog.pg_stat_replication"
12+
Column | Type | Collation | Nullable | Default
13+
------------------+--------------------------+-----------+----------+---------
14+
pid | integer | | |
15+
usesysid | oid | | |
16+
usename | name | | |
17+
application_name | text | | |
18+
client_addr | inet | | |
19+
client_hostname | text | | |
20+
client_port | integer | | |
21+
backend_start | timestamp with time zone | | |
22+
backend_xmin | xid | | |
23+
state | text | | |
24+
sent_lsn | pg_lsn | | |
25+
write_lsn | pg_lsn | | |
26+
flush_lsn | pg_lsn | | |
27+
replay_lsn | pg_lsn | | |
28+
write_lag | interval | | |
29+
flush_lag | interval | | |
30+
replay_lag | interval | | |
31+
sync_priority | integer | | |
32+
sync_state | text | | |
33+
reply_time | timestamp with time zone | | |
34+
```
35+
36+
此视图包含物理复制 (仅限于使用流复制的情况,非 WAL 传输方式) 和逻辑复制的信息。延迟情况在此视图中可以通过字节 (lsn 相关列) 或时间间隔 (lag 相关列) 进行衡量,并且可以为每个复制流观察到多个步骤。
37+
38+
要分析此视图中的 LSN 值,我们需要将它们与所连接服务器上的当前 `LSN` 值进行比较:
39+
40+
- 如果是主服务器 (`pg_is_in_recovery()` 返回 false ),则使用 `pg_current_wal_lsn()`
41+
- 否则 (备节点领导节点),使用 `pg_last_wal_replay_lsn()`
42+
43+
可以使用 `pg_wal_lsn_diff()` 函数或 `-` 操作符进行 LSN 的差值计算。
44+
45+
文档:[Monitoring pg_stat_replication view](https://postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW).
46+
47+
以下是一些查询延迟的示例:
48+
49+
- [Netdata](https://github.com/netdata/netdata/blob/9edcad92d83dba359f5eb6c06d0741b50030edcf/collectors/python.d.plugin/postgres/postgres.chart.py#L486)
50+
- [Postgres exporter for Prometheus](https://github.com/prometheus-community/postgres_exporter/blob/2a5692c0283fddf96e776cc73c2fc0d5caed1af6/cmd/postgres_exporter/queries.go#L46)
51+
52+
## 在物理备节点上
53+
54+
当连接到物理备节点时,获取其延迟时间间隔:
55+
56+
~~~sql
57+
select now() - pg_last_xact_replay_timestamp();
58+
~~~
59+
60+
在某些情况下,`pg_last_xact_replay_timestamp()` 可能返回 `NULL`
61+
62+
- 如果备节点刚刚启动并且尚未重放任何事务;
63+
- 如果主节点上没有最近的事务。
64+
65+
`pg_last_xact_replay_timestamp()` 的这种行为可能会导致错误的结论,认为备节点存在延迟,且复制不健康 — 这在低负载的环境 (例如非生产环境) 中并不罕见。
66+
67+
文档:[pg_last_xact_replay_timestamp](https://postgresql.org/docs/current/functions-admin.html#id-1.5.8.33.6.3.2.2.4.1.1.1).
68+
69+
------
70+
71+
## 逻辑复制
72+
73+
在主节点 (在逻辑复制上下文中通常称为"发布端") 上可以观察到复制延迟。除了前面讨论的 `pg_stat_replication`,还可以使用 `pg_replication_slots`
74+
75+
```sql
76+
select
77+
slot_name,
78+
pg_current_wal_lsn() - confirmed_flush_lsn as lag_bytes
79+
from pg_replication_slots;
80+
```
81+
82+
------
83+
84+
## 混合情况:逻辑和物理复制
85+
86+
在某些情况下,你可能需要同时处理逻辑复制和物理复制。例如,考虑以下情况:
87+
88+
- 集群 A:一个由 3 个节点 (主节点 + 2 个物理备节点) 组成的常规集群。
89+
- 集群 B:也是主节点 + 2 个物理备节点,且主节点通过逻辑复制连接到集群 A 的主节点。
90+
91+
这是一种典型的情况,通常在涉及逻辑复制的复杂更改 (例如大版本升级) 时会发生。在某些时候,你可能希望将部分只读流量从集群 A 的备节点重定向到集群 B 的备节点。
92+
93+
在这种情况下,如果我们需要了解每个节点的延迟情况,并且希望代码能很好地适用于所有节点,这可能会有些棘手。
94+
95+
以下是解决方法 (感谢来自 GitLab 的 [Dylan Griffith](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121621)),假设我们可以从我们正在分析的节点和集群 A 的主节点获取信息 (记住上面的所有评论):
96+
97+
首先,获取主节点的 LSN:
98+
99+
```sql
100+
select pg_current_wal_lsn() as primary_lsn;
101+
```
102+
103+
然后获取观察节点的 LSN 位置,并使用它来计算以字节为单位的延迟值:
104+
105+
```sql
106+
with current_node as (
107+
select case
108+
when exists (select from pg_replication_origin_status) then (
109+
select remote_lsn
110+
from pg_replication_origin_status
111+
)
112+
when pg_is_in_recovery() then pg_last_wal_replay_lsn()
113+
else pg_current_wal_lsn()
114+
end as lsn
115+
)
116+
select lsn – {{primary_lsn}} as lag_bytes
117+
from current_node;
118+
```

0 commit comments

Comments
 (0)