WAL 脚本

WAL 脚本

我目前有 1 台主服务器(a)和 3 台直接来自主服务器的复制服务器(b、c、d),我使用的 archive_command 是以下脚本:https://gist.github.com/Geesu/8640616

所有服务器都是 Ubuntu 12.04.4,运行 PostgreSQL 9.2.6

以下是每个复制服务器的 recovery.conf:https://gist.github.com/Geesu/8640635

奇怪的是,在我启动复制服务器大约 6 小时后,其中 2 个服务器立即落后,现在正在努力追赶,但它们的落后程度越来越大。以下是它们与主服务器相比的落后程度:

a 20287.825072
b 2.521136
c 19994.51653

有谁知道为什么其中一台服务器几乎完全赶上进度,而其他服务器却一直落后?我已经验证了 a 和 c 正在处理 WAL 段,只是速度不够快。

来自 a 和 c 的一些日志示例:

cp: cannot stat `/var/lib/postgresql/9.2/archive/000000080000109E0000009A': No such file or directory
2014-01-26 23:02:14 GMT LOG:  record with zero length at 109E/9AE622D8
cp: cannot stat `/var/lib/postgresql/9.2/archive/000000080000109E0000009A': No such file or directory
2014-01-26 23:02:14 GMT LOG:  streaming replication successfully connected to primary
2014-01-26 23:03:36 GMT FATAL:  could not receive data from WAL stream: SSL error: sslv3 alert unexpected message

cp: cannot stat `/var/lib/postgresql/9.2/archive/000000080000109E000000B9': No such file or directory
2014-01-26 23:03:41 GMT LOG:  record with zero length at 109E/B9E797E0
cp: cannot stat `/var/lib/postgresql/9.2/archive/000000080000109E000000B9': No such file or directory
2014-01-26 23:03:41 GMT LOG:  streaming replication successfully connected to primary

也许这有关系?最终它将获得适当的 WAL 段并进行处理。

关于如何进一步调试这个问题,有什么建议吗?

答案1

这里有一些错误。

WAL 脚本

尝试推送到每台服务器,直到全部成功

首先,您的主服务器正在(或正在尝试)将 WAL 存档推送到每个副本,并且只有当所有三个副本都收到文件时,archive_command 才会被视为成功。这意味着如果其中一个发生故障,其他两个将停止接收新的 WAL,因为主服务器上的 Pg 将一直停留在一遍又一遍地重试同一个段的状态。

失败时没有注意到

您的脚本实际上无法返回$FAIL,因此实际上这不起作用 - 即使所有三个服务器都无法接收 WAL 文件,它也会报告成功。它将继续处理 WAL 文件,而忽略先前的失败意味着整个序列毫无用处并且无法重播的事实。这很可能解释了为什么副本找不到本地 WAL 段;它们可能由于环境变量问题(RSYNC_RSH)、已知主机问题、ssh 密钥问题等而无法复制。

如何修复 wal 发送方脚本

我强烈建议您切换到推/拉模型。让主服务器将 WAL 迁移到可靠的存储位置。然后让副本从该位置复制文件。主服务器只需复制一次文件,并且不必担心在不同服务器的不同点重试(如果某些服务器宕机,其他服务器正在追赶等)。Amazon S3 是一个越来越受欢迎的选择,尽管 Windows Azure Block Service (WABS) 和 OpenStack 的 Swift 也很有用。一个有用的工具是沃尔沃,可以作为您的archive_commandrestore_command;它支持所有列出的商店。

方便的是,如果您使用 S3,您可以制定一个存档策略,将旧内容存储在 Glacier 中而不是删除它,然后在很久以后删除它。这是一种便宜又方便的存储此类内容的方法“以防万一” - 但请记住,除非您也存储了相关的基本备份,否则它是无用的!

如果你必须让主服务器推送到所有三个后端,你需要更加聪明地使用它,使用一个脚本来单独跟踪哪些服务器收到了每个 WAL 段,并在一台服务器收到段时报告成功以及所有先前的片段。您需要一个后台作业,不断重试落后的服务器。即便如此,这也是一个坏主意;它会使您的 WAL 归档速度与最慢的服务器一样慢,这确实不理想,并且会导致主服务器严重占满。我相信这可以工作,但在我看来它太脆弱和复杂了。

流复制已损坏-SSLv3重新协商错误?

在您的日志中:

2014-01-26 23:03:36 GMT 严重错误:无法从 WAL 流接收数据:SSL 错误:sslv3 警报意外消息

您的服务器已设置流式复制,但它们存在 SSL 问题。这是 sslv3 重新协商问题的签名错误,以及早期的 OpenSSL 对此的愚蠢“修复”。确保您已更新到最新的 OpenSSL 补丁版本,因为这应该可以解决问题。

如果没有,作为一种解决方法,您可以尝试ssl_renegotiation_limit=0postgresql.conf请参阅这个启动板错误

相关内容