根据 IBM 文档,故障恢复的定义是“在灾难或计划维护期后将生产返回到原始位置的过程”。
根据我对 postgresql 社区帖子的阅读,在故障转移后将旧的主服务器重新联机作为新主服务器之后的备用服务器也可能被视为故障转移。
这可能是因为人们普遍认为拥有相同的数据库服务器是最佳实践。但是,这个选项对我来说不可用。
我有 2 台服务器:Costanza 和 Kramer。Costanza 是一个高性能服务器。克莱默不是。
这是我正在尝试逐步优化的场景:
- Costanza 处于不可恢复的故障模式(典型)
- 克莱默升入小学
- Costanza 再次可用且 PGDATA 完好无损
- 同步 Costanza 和 Kramer,这样写入 Kramer 的数据就不会丢失
- 将科斯坦萨提升为主要地位
- 建立克莱默作为备用
我专注于步骤 4 和 5。
当运行 pg_rewind 重放 WAL 文件时,似乎“在最新公共检查点之后源服务器上发生的修改被忽略 - 当目标服务器成为源服务器的备用服务器时,这些修改无论如何都会被恢复。” --看到这个SO问题
我由此推断,简单地运行 pg_rewind 不会同步 Costanza 和 Kramer(步骤 4),因为对 Kramer 的写入可能发生在最后一个公共检查点之后。这也是我们在进行故障恢复时观察到的情况。
我对第 4 步的解决方案是:
4a. 运行 pg_rewind 来同步不同的时间线
4b. 将 Costanza 建立为 Kramer 的备用数据库,并允许其赶上复制延迟(假设检查点后存在 WAL)
然后
- 关闭克莱默并将科斯坦萨提升为初选(再次导致时间线分歧)
6a. 以 Kramer 作为目标运行 pg_rewind
6b. 将 Kramer 建立为 Costanza 的备用数据库,并允许其赶上复制延迟(再次假设检查点后存在 WAL)
这是一种罕见的情况。但我不知道我会遇到什么故障模式以及 PGDATA 是否完好无损。
这是一个非常大的数据库,我希望尽可能避免通过基础备份移动数据。
这种方法对我来说似乎效率低下,因为我必须运行 pg_rewind 两次,并且我必须将 Costanza 建立为备用数据库,以便应用 Kramer 发布公共检查点时发生的修改。
我必须最大限度地减少数据丢失,而该解决方案似乎可以通过最少的数据传输来做到这一点。
(旁白:我是否应该关心额外的时间线创建?这似乎是不可避免的,并且它发生在将数据库升级为主数据库时)
有没有办法将克莱默后公共检查站的修改应用到科斯坦萨,而不将科斯坦萨建立为克莱默的备用?
是否存在达到同等结果的更短路径?或者,在数据库故障场景中,是否存在您认为“更容易”遵循的路径?
在回答您的问题之前,请允许我指出您忘记了故障转移过程中非常重要的一步:在步骤 1 和 2 之间,您必须确保 Constanza 已关闭。这可能看起来微不足道,但如果您不这样做,可能会发生某些客户端仍然连接到 Constanza 上的数据库的情况,最终会出现“裂脑”场景,这可能比延长停机时间更糟糕。
除此之外,您的步骤相当准确,但比必要的更复杂。将 Constanza 转为备用状态并让它赶上 Kramer 后,您对 Kramer 执行干净关闭。这确保了对 Kramer 的所有更改都会复制到 Constanza,并且不需要
pg_rewind
. 您所要做的就是确保primary_conninfo
克莱默指向康斯坦萨并standby.signal
在克莱默上创建。如果您正在使用复制槽,则每次故障转移和切换还需要在升级后创建它们,因为复制槽尚未(从 PostgreSQL v16 开始)被复制。
最后,我认为克莱默比康斯坦莎弱是一个糟糕的设置。如果 Kramer 无法处理负载,您的高可用性设置将无法提供高可用性。