数据库 频道

PostgreSQL:支持故障转移的复制槽

     译者简介:张岩&崔鹏&海能达DBA团队,任职于海能达通信股份有限公司哈尔滨平台中心,数据库开发高级工程师,致力于PostgreSQL数据库在专网通信领域、公共安全领域的应用与推广,个人兴趣主要集中在:分布式数据库系统设计、高并发高可用数据库架构设计与开源数据库的源码研究。

  校对者简介:赵全明 任职于华为技术有限公司,数据库内核开发工程师,致力于PostgreSQL在全行业的应用与推广。

  逻辑解码和逻辑复制在PostgreSQL生态中受到了越来越多的关注。这意味着我们需要它与生产HA系统一起很好地工作——但事实证明这存在一个问题。复制槽并没有被同步到备机上,因此主机一旦发生故障,备机升主后,原来的复制槽将不能继续使用。

  有一个补丁(支持故障转移的复制槽)可以改变这一现状,方法是通过WAL归档或者流复制把复制槽创建、更新同步到备机上。这使得逻辑解码客户端可以无缝地切换到因故障转移被提升的新主机上,并继续重放,而不再有一致性问题。

  逻辑解码和复制槽

  在9.4中引入的逻辑解码可以让客户端按照一致的事务提交顺序逐行地将更改流式传送到接收端——它可以是另一个PostgreSQL实例,也可以是您选择的消息队列和搜索引擎等应用程序。

  为了流式传输数据,客户端连接到服务器上的复制槽。插槽确保服务器保留解码所需的WAL,并且(对于逻辑插槽)还防止删除理解WAL可能需要的旧版本的系统表行。

  故障转移的问题

  大多数生产PostgreSQL部署依赖于流复制和/或基于WAL归档的复制(“物理复制”)作为其高可用性和故障转移能力的一部分。与大多数服务器状态不同,复制槽不会从主服务器复制到其副本上。当主服务器失败并提升一个副本时,来自主服务器的复制槽都将丢失。因为它们没有槽可以用来连接,逻辑复制客户端无法继续传输。

  请不要紧张!只需在副本上创建一个具有相同名称的槽。

  事情也没那么简单。在创建逻辑复制槽时,只能使用数据库历史视图(相对于创建槽时的未来位置)来创建。因此,如果客户机没有完全被跟上旧主服务器上的relay时,或者新主服务器上做的第一件事在并不是创建一个替代的插槽,那么客户机将丢失一些更改。这就是插槽要防止的问题,对于某些应用程序来说,这可能是一个关键问题。

  槽不能“回到过去”创建的两个关键原因是WAL保留和(对于逻辑槽)系统表的清空。我们也无法导出过去的快照,但这只是新增客户端碰到的问题。WAL保留是最简单的:备用服务器可能会丢弃与数据库更改相对应的WAL段,因为主服务器上的逻辑解码客户机还没有Replay这些更改。如果发生故障转移,则无法将这些更改Replay到该客户机。

  另一个问题是系统表——逻辑解码需要使用表、类型等的历史定义来解释WAL中的数据,为此,它使用删除的行进行一种基于MVCC的时间遍历。

  如果主服务器上的VACUUM删除了那些被删除的行,并将这些空间标记为可重用的空闲空间,那么备用服务器将Replay这些更改,而我们再也无法理解WAL的内容了。

  故障转移槽

  故障转移槽通过同步槽的创建、删除和复制服务器的位置更新来解决这些问题。这是通过WAL stream完成的,就像其它的操作一样。如果创建了一个故障转移槽(开启了故障转移选项 pg_create_logical_replication_slot),那么它的创建将被记录在WAL中。当客户端告诉服务器它可以释放不再需要的资源时,随后的位置更新也是如此。

  如果主服务器故障,而备用服务器升主,逻辑解码客户端可以重新连接到备用服务器,就像什么都没有发生一样继续运行。

  如果在升主的同时进行了DNS更新或IP切换,逻辑解码客户端甚至认为最多只是发生了一次主机重启。

  关于物理插槽

  PostgreSQL的块级(“物理”)复制也有复制插槽。它们可以用于固定WAL保留,提供了一种比wal_keep_segments更细粒度的机制,但代价也是无界的。可以创建物理故障转移槽,就像创建逻辑故障转移槽一样。

  这是否意味着pglogical可以用于故障转移到逻辑副本?

  故障转移槽设计初衷并不是支持故障转移到逻辑副本上。它们的存在是为了允许逻辑复制跟随物理故障转移。

  支持故障转移到逻辑副本是一个完全不相关的问题。在PostgreSQL内核中有一些与之相关的限制,比如目前缺少对序列位置推进的逻辑解码的支持。故障转移槽在这方面既没有帮助也没有消弱。它们只是提供了一种方法,可以将逻辑复制集成到HA解决方案中,并集成到现有的成熟和已建立的基础设施模式中。

1
相关文章