PostgreSQL 流复制停止更新

Jer*_*son 2 postgresql performance postgresql-9.5 postgresql-performance

我有四个 PostgreSQL 9.5 实例在 EC2 上运行,使用 m4.8xlarge 实例,RAID0 设置中有五个 PIOPS SSD 和一个单独的 XLOG 驱动器。直到今天早上,我的复制延迟从未超过一两分钟,但现在复制在大约 30 分钟后在所有实例上完全失败。

重新启动 Postgres 将问题再解决半小时。

没有 CPU 争用,iowait 通常小于 1%。阻止对服务器的读取,认为它可能会不堪重负,什么也不做。我无法弄清楚这里的问题是什么,除了亚马逊的问题。

谁能给我一些想法如何解决这个问题?日志中没有任何内容,replay_location(来自 pg_stat_replication)只是停止更新,直到我重新启动从站。

Jer*_*son 5

TL;DR:不要max_standby_streaming_delay在配置中禁用。

为了其他人在这个问题上寻找答案,我想我会回答我自己的问题,因为通过谷歌关于这个主题的信息量非常少。

四处挖掘,我设法发现了一本名为《PostgreSQL 故障排除》的书:https : //www.packtpub.com/big-data-and-business-intelligence/troubleshooting-postgresql

它采用电子书格式,对帮助我追踪我遇到的问题很有用。它描述了使用一个名为的工具pg_view,该工具具有许多关于 PostgreSQL 服务器中发生的事情的非常有用的实时指标。

在我的一台已停止复制的服务器上运行它表明在长时间运行的查询期间出现了问题:

db.server.com up 21:34:25 36 cores Linux 4.4.5-15.26.amzn1.x86_64 load average 1.79 0.94 0.47                                                                                                                                               08:58:29
 sys: utime 5.7   stime 0.1   idle 94.3  iowait 0.0   ctxt 580 run 4   block 0
 mem: total 59.0GB free 2.3GB  buffers 41.0MB cached 55.0GB dirty 692KB  limit 29.5GB as 14.7GB left 14.8GB
 /var/lib/pgsql/9.5/data 9.5.2 standby connections: 5 of 500 allocated, 2 active
 type dev     fill   total    left   read  write    await path_size path
 data md127    0.0 499.7GB 382.8GB    0.0    0.1      0.0   116.6GB /var/lib/pgsql/9.5/data
 xlog xvdg     0.0 100.0GB  84.0GB    0.0    0.6     15.7    15.9GB /var/lib/pgsql/9.5/data/pg_xlog
   pid type    s utime stime guest read write   age  uss db   user     query
 26644 backend R 100.2   0.0   0.0  0.0   0.0 03:21 93.4 data postgres WITH query AS ( WITH original_transaction_id AS( SELECT original_transaction_id FROM table WHERE...
 26645 backend R  99.3   0.0   0.0  0.0   0.0 00:01 93.8 data postgres WITH query AS( SELECT COUNT(id) AS total, original_transaction_id FROM table GROUP BY original_tr...
Run Code Online (Sandbox Code Playgroud)

关键是age显示长时间运行的查询的列。然而,秘诀是通过按“s”热键来显示服务器上的所有进程,GitHub页面中没有描述。这显示了系统进程,包括启动和 WAL 接收器:pg_view

   pid type            s utime stime guest read write   age  uss db   user     query
 12169 startup         S   0.0   0.0   0.0  0.0   0.0        1.2               recovering 000000010000070A0000006D...
 12170 checkpointer    S   0.0   0.0   0.0  0.0   1.9        1.2               ...
 12171 writer          S   0.0   0.0   0.0  0.0   0.0        1.0               ...
 12172 stats collector S   0.0   0.0   0.0  0.0   0.0        1.2               ...
 12178 wal receiver    S   0.0   1.0   0.0  0.0   1.1        1.2               streaming 70A/6D998000...
Run Code Online (Sandbox Code Playgroud)

有用的信息startup在它说的那一行recovering。这是正常的,因为它是一个只读从设备,并且在新数据通过 wal 接收器传入时在技术上总是会恢复

问题是当它waiting位于该行的末尾时 - 这告诉您服务器卡在等待长时间运行的查询以释放它需要更新的表上的锁,并且直到它这样做,复制才会停止,或max_standby_streaming_delay达到该值。

默认情况下,max_standby_streaming_delay设置为 30 毫秒。但是,它在我的服务器上被禁用,可能是为了提高复制可靠性:

max_standby_streaming_delay = -1
Run Code Online (Sandbox Code Playgroud)

从配置文件中删除该行并重新加载解决了问题。 总正常运行时间

另一个结果是我们将所有长时间运行的查询移动到一个单独的副本,仅使用我的这些后端进程来帮助长期可靠性并避免面向客户的数据库上可能的表锁定。

大多数故障排除指南都说复制问题与网络有关,但在这种情况下,它是配置错误和格式错误的 SQL 查询。