跳到主要内容

复制概述

多个数据库服务器可以一起工作,这样如果主要的服务器故障则允许其它服务器快速接手它的任务(高可用性),或者可以允许多个计算机提供相同数据(负载均衡)。理想情况下,数据库服务器能够无缝地一起工作。Halo 数据库支持物理复制技术和逻辑复制技术来保证数据库系统的可靠性和数据安全性。

物理复制​

物理复制技术采用流的方式传输 WAL 日志。其基本原理是将主库的 WAL 日志在从库进行应用,从而获得跟主库一致的数据。从库主动连接到主库,主库则在 WAL 记录产生时即将它们以流的方式传送给从库,这一过程不必等到 WAL 文件被填充,因而可以保证主备之间的延迟非常低(即使是默认异步的情况下)。

逻辑复制​

简单点说,逻辑复制就是将主库上的操作序列在从库上进行重放的过程。比如在主库 UPDATE,从库捕获该 UPDATE 命令,并在自己的库里执行一样的 UPDATE 命令,从而实现了数据的一致。逻辑复制使用发布和订阅模型。逻辑复制与发布订阅的完整操作参见全域数据库及附录D 扩展模块。

级联复制​

级联复制特性允许从库接收复制连接并且把 WAL 记录再次以流的方式传送给其他从库,就像一个转发器一样。这可以被用来减小对于主库的直接连接数并且使得站点间的带宽开销最小化。

复制槽​

复制槽提供了一种自动化的方法来确保主库在所有的后备机收到 WAL 日志段之前不会移除它们,并且主库也不会移除可能导致恢复冲突的行,即使从库断开的情况下依然能够保证。

查询复制槽

每个复制槽都有一个名字,名字可以包含小写字母、数字和下划线字符。已有的复制槽和它们的状态可以在 pg_replication_slots 视图中看到。

创建复制槽

使用内置函数 pg_create_physical_replication_slot 来创建复制槽。一个典型的例子如下:

# SELECT * FROM pg_create_physical_replication_slot('a_slot');
slot_name | lsn
-----------+-----
a_slot |
(1 row)

删除复制槽

使用内置函数 pg_drop_replication_slot 来删除一个复制槽。一个典型的例子如下:

# SELECT * FROM pg_drop_replication_slot('a_slot');
pg_drop_physical_replication_slot
------------------------------------

(1 row)

同步复制​

Halo 支持同步复制。默认情况下,Halo 采用异步复制的方式,如果主库崩溃,则某些已被提交的事务可能还没有被复制到从库,这会导致数据丢失。数据的丢失量与故障转移时的复制延迟成比例。同步复制能够保证一个事务的所有修改都能被传送到一台或者多台同步从库。这提升了由一次事务提交所提供的标准持久化级别。Halo 提供了 2 种保护级别。当 synchronous_commit 为 on 或者 remote_apply 时,提供 2-safe 保护级别;当 synchronous_commit 为 remote_write 时,提供 group-1-safe 保护级别。

当使用同步复制时,需要在主库上指定同步复制的备库名称,在 postgresql.conf 中配置 synchronous_standby_names ='备库名称',同时备库需要在 primary_conninfo 中配置连接参数 application_name=备库名称:

primary_conninfo = 'application_name=node2 user=replica password=123456 channel_binding=prefer host=node1 port=1921 sslmode=prefer sslcompression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=halo target_session_attrs=any'

配置完成后,重启备库 pg_ctl restart,主库再启动同步复制 pg_ctl restart。

主库查询状态:

halo0root=# select application_name,client_addr,state,sync_state from pg_stat_replication;
application_name | client_addr | state | sync_state
------------------+--------------+----------+------------
node2 | 192.168.56.109 | streaming | sync
(1 行记录)

在同步复制场景下,一个写事务的每次提交将一直等待,直到收到一个确认表明该提交在主库和从库上都已经被写入到磁盘上的 WAL 日志中。只读事务和事务回滚不需要等待从库的回复。子事务提交也不需要等待从库的响应,只有最外层的提交才需要等待。

分组复制​

分组复制(Multi-group Replication)在传统流复制的基础上,将多个备库划分到不同分组,为每组配置独立的同步级别(synchronous_commit),实现差异化的复制可靠性策略。

传统流复制只能为整个集群配置单一全局同步级别,难以适配"同机房严格同步 + 跨机房宽松同步"的混合部署场景。分组复制通过引入 synchronous_standby_namesX 与 synchronous_commitX(X 为 1~4)参数,将备库划分为不同分组:主分组承担核心同步任务,额外分组适配异地容灾等差异化场景。详见分组复制。

可查询从库​

Halo 的从库可以提供只读查询的能力。该功能通过 hot_standby 参数进行设置。