PostgreSQL 复制(同步和异步复制)是数据库社区中最广泛使用的功能之一。如今,人们正在构建高可用性集群或使用复制来创建只读

副本来分散工作负载。这里需要注意的是,如果您使用复制,则必须确保您的集群受到正确监控。

这篇文章的目的是解释一些基础知识,以确保您的 PostgreSQL 集群保持健康。

pg_stat_replication:检查当前状态

监控复制的最佳方法是使用 pg_stat_replication,它包含很多重要信息。视图如下所示:

test=# \d pg_stat_replication
                 View "pg_catalog.pg_stat_replication"
Column           | Type                    | Collation | Nullable | Default
-----------------+-------------------------+-----------+----------+---------
pid              | integer                 |           |          |
usesysid         | oid                     |           |          |
usename          | name                    |           |          |
application_name | text                    |           |          |
client_addr      | inet                    |           |          |
client_hostname  | text                    |           |          |
client_port      | integer                 |           |          |
backend_start    | timestamp with time zone|           |          |
backend_xmin     | xid                     |           |          |
state            | text                    |           |          |
sent_lsn         | pg_lsn                  |           |          |
write_lsn        | pg_lsn                  |           |          |
flush_lsn        | pg_lsn                  |           |          |
replay_lsn       | pg_lsn                  |           |          |
write_lag        | interval                |           |          |
flush_lag        | interval                |           |          |
replay_lag       | interval                |           |          |
sync_priority    | integer                 |           |          |
sync_state       | text                    |           |          |
reply_time       | timestamp with time zone|           |          |

多年来,此视图中的列数大幅增加。不过,我们首先讨论一些基本原理。

pg_stat_replication:WAL sender信息

人们常说 pg_stat_replication 位于“primary”上。这不完全正确。该视图的作用是公开有关 wal_sender 进程的信息。换句话说:如

果你正在运行级联复制,这意味着当一个从服务器复制到其他从服务器时,它可能也会显示条目。这是一张说明情况的图片:

对于每个 WAL sender进程,您将得到一个条目。重要的是,每个服务器只能看到链中的下一个服务器——发送服务器永远不会“看穿”从服务器。换句话说:在级联复制的情况下,您必须要求每个发送服务器获取概览。

还有更多:人们通常必须确定备库是否是最新的。这里有很多相关的事情:

  • sent_lsn:已经通过网络发送了多少 WAL?
  • write_lsn:已向操作系统发送了多少 WAL?(未刷盘)
  • lush_lsn:有多少 WAL 已刷新到磁盘?
  • replay_lsn:已经重播了多少 WAL,因此对查询可见?

下图说明了这些字段:

这里需要注意的是,PostgreSQL 提供了一种特殊的数据类型来表示这些数据:pg_lsn

可以轻松地找出当前的 WAL 位置。下面是它的工作原理:

test=# SELECT pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
        3/DA06D240
(1 row)

这里值得注意的是可以进行计算:

test=# SELECT pg_current_wal_lsn() - '3/B549A845'::pg_lsn;
  ?column?
-----------
 616376827
(1 row)

PostgreSQL 提供了各种运算符来执行此类计算。换句话说:很容易找出备库落后了多远。

flush_lsn 与 replay_lsn

人们一直在问我们flush_lsnreplay_lsn之间有什么区别。好吧,让我们深入研究一下:当WAL从主节点流向从节点时,它首先通过

网络发送,然后发送到操作系统,最后将事务刷新到磁盘,以确保持久性(=崩溃安全)。flush_lsn 显然表示最后一次刷写到磁盘的WAL

位置。现在的问题是:数据刷新后是否可见?答案是不,可能会有复制冲突。在发生复制冲突的情况下,WAL会持久化在备库上,只有

在冲突解决后才会重放。换句话说,可能发生的情况是,数据存储在从服务器上,但尚未重放使得用户最终可以访问。

注意这一点很重要,因为复制冲突发生的频率可能比您想象的要高。如果您看到如下消息,则说明您遇到了复制冲突:

ERROR: canceling statement due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.

复制滞后

有时需要确定复制延迟量(以秒为单位)。到目前为止,我们已经看到了两个服务器之间的距离(以字节为单位)。如果您想测量滞后,

可以查看 _lag 列。这些列的数据类型是“间隔”,因此您可以看到延迟是多少秒甚至几分钟。如果复制工作正常,延迟通常非常非常小

(毫秒)。但是,您可能想要监视它。

需要注意的是:如果您正在运行大规模导入,例如 VACUUM 或其他一些昂贵的操作,很容易发生磁盘吞吐量高于网络带宽的情况。在这

种情况下,备库很有可能落后。您必须容忍这种情况,并确保警报不会过早启动。

pgwatch2:现成的工具

要监视复制,您可以依赖我刚才展示的手动魔术。然而,也有很多现成的工具来促进这项任务。我们可以推荐pgwatch2,它可以作为一

个容器免费下载。

posted on 2024-01-15 21:52  jl1771  阅读(96)  评论(0编辑  收藏  举报