流复制
本章主要介绍 Vastbase 数据库的流复制特性。
流复制是一种基于预写式日志(WAL)的数据同步方式,流复制会持续向备节点发送 WAL 日志。
流复制与逻辑复制的差异
流复制也称为物理复制,这是由于流复制的原理是主节点将 WAL 日志以流的方式发送给备节点,备节点在接收到 WAL 日志后,进行 WAL 回放;而相较于物理复制,Vastbase 支持的另一种复制方式即逻辑复制,逻辑复制是基于 WAL 进行逻辑解析。有关逻辑复制的详细信息,请参见《Vastbase 管理员指南》的逻辑复制章节。
因此,流复制与逻辑复制主要有以下差异:
复制过程:流复制基于WAL日志,主库把WAL发送给备库,备库接收WAL后进行回放;逻辑复制会根据预先设置好的规则对WAL日志进行解析,即将WAL二进制文件解析成一定格式的逻辑变化信息(SQL语句),例如从WAL中解析指定表上发生的DML逻辑变化信息,然后主节点将逻辑变化信息发送给备节点,备节点收到 WAL 逻辑解析信息后再应用日志。
粒度:流复制是基于实例级别的复制;逻辑复制是基于表级别。
操作:流复制支持DML,DDL操作;逻辑复制仅支持DML操作,Vastbase G100 V2.2 Build 14版本开始,逻辑复制也支持部分DDL操作,详见逻辑复制支持DDL。
应用场景:流复制主节点可读可写,备节点只读,适用于高可用、读写分离等场景;逻辑复制各个节点均可读可写,适用于部分表的复制、异构数据库的数据同步等场景。
WAL 级别
WAL 日志记录数据库的变化,格式为二进制,当主节点出现异常,如果 WAL 文件已经写入,但数据还没有持久化,Vastbase 数据库会在再次启动时根据 WAL 日志文件信息进行回放,从而保证数据一致性。Vastbase 数据库正是通过流复制将 WAL 同步到备库进行回放。
Vastbase 支持四种 WAL 模式:minimal、archive、hot_standby 与 logical。
minimal
默认配置,仅写入崩溃或突发关机时所需要的 WAL 信息(不建议使用)。
archive
archive 模式下,相比于默认的 minimal 模式增加了 WAL 归档需要的日志信息,从而可以支持数据库的归档恢复。
hot_standby
hot_standby 模式下,可以使用流复制。WAL日志记录的信息与archive相同,但增加了用于重建正在运行的事务状态所需的信息。换言之,若要在备节点执行只读查询(Read-only Query),则主节点的 wal_level 需要设置在 hot_standby 模式,并且备节点需要启用 hot_standby。
logical
logical 模式下,支持逻辑复制。
流复制选项
同步方式
Vastbase 数据库支持同步流复制与异步流复制两种同步方式。
在同步模式复制中,只有当这些更改已复制到所有副本时,主数据库上的事务才被视为完成。备节点必须始终可用,以便在主节点上完成事务。同步复制模式用于具有即时故障转移要求的高端事务环境。
在异步模式下,当只在主节点上完成更改时,可以声明主节点上的事务已完成。这些更改随后会及时复制到副本中。备节点可以在一段时间内保持不同步。在崩溃的情况下,可能会发生数据丢失,但异步复制提供的开销很小,不会使主节点负担过重。
通常情况下,一个事务产生的日志的同步顺序如下:
1、主机将日志内容写入本地内存。
2、主机将本地内存中的日志写入本地文件系统。
3、主机将本地文件系统中的日志内容刷盘。
4、主机将日志内容发送给备机。
5、备机接受到日志内容,存入备机内存。
6、备机将备机内存中的日志写入备机文件系统。
7、备机将备机文件系统中的日志内容刷盘。
8、备机回放日志,完成对数据文件的增量更新。
GUC 参数 synchronous_commit 用于指定事务同步方式,开启后,备节点可以在主节点提交后直接读取已提交的数据。
在主备流复制中,synchronous_commit 的取值:
设置为 off 时,提交事务时不需要等待本地相应 WAL 数据写入本地 WAL 日志即可向客户端返回成功。
设置为 local 均表示提交事务时需等待相应 WAL 数据写入本地 WAL 日志文件后才向客户端返回成功。
设置为 remote_receive 表示当主节点提交事务时,需等待备节点接收到主节点发送的 WAL 日志流后(无需写入文件系统),就向客户端返回成功。
设置为 remote_write 表示当主节点提交事务时,需等待备节点接收主节点发送的 WAL 日志流并写入备节点的文件系统后,才向客户端返回成功。
设置为 on 表示主节点提交事务时,需等待备节点接收数节点发送的 WAL 日志流并写入 WAL 文件后,才向客户端返回成功。
设置为 remote_apply 表示主节点提交事务时,需等待备节点完成相应数据的持久化后,才向客户端返回成功。
主备复制
主备复制是指所有备节点都接收主节点的 WAL 日志的复制方式。
主备复制的方式支持同步复制与异步复制。
GUC 参数 replconninfoN 用于设置本端侦听和鉴权的第N个节点信息,其中N表示第几个节点,取值为 1~18。
该参数是用来复制连接信息,用于将主服务器连接到备用服务器上,或将主服务器或备用服务器连接到辅助服务器上。该参数包含如下几部分内容:
localhost:本地服务器IP地址。
localport:本地端口号,同步日志传输端口。
localheartbeatport:集群心跳端口号。
localservice:主备通讯端口。
remotehost:远程服务器IP地址
remoteport:远程端口号,同步日志传输端口。
remoteheartbeatport:集群心跳端口。
remoteservice:主备通讯端口。
GUC 参数 synchronous_standby_names 用于指定潜在同步复制的备机名称列表,每个名称用逗号分隔。
当前连接的同步备机是列表中的第一个名称。如果当前同步备机失去连接,则它会立即更换下一个优先级更高的备机,并将此备机的名称放入列表中。
备机名称可以通过设置环境变量 PGAPPNAME 指定。
级联复制
Vastbase 数据库支持级联复制,级联复制是指对于三节点以上的 Vastbase 集群中,其中一台备节点既是 WAL 日志的接收者,又是 WAL 日志的发送者。换言之,级联复制要求其中一台备节点作为流复制的中继,这种方式可以有效减少主节点的直连数量,最小化带宽开销。
同时作为 WAL 接收者与发送者的备节点称为备节点,备节点接收主节点的 WAL 日志,向级联备节点发送 WAL 日志。级联复制为异步复制。
特别地,如果备节点在故障恢复的过程中成为主节点,则会终止与级联备节点的复制连接。
流复制槽
每一个流对应一个复制槽。复制槽是为了防止主节点删除还未发送到备节点的 WAL 日志,即使备节点意外离线,也不会删除备节点所需的 WAL 日志。
需要注意的是,正是由于复制槽的存在会使得主节点不断地积累需要发送给备节点的 WAL 日志,因此如果备节点离线时间过长,由于复制槽的存在会导致主节点的 WAL 日志大量堆积。
GUC 参数 wal_keep_segment 用于控制主节点为备节点保留的 wal 日志最大数量。主节点上 WAL 日志留存越多,允许备节点离线的时间越长;尽管将该参数设置为一个较大的值能够保证备节点数据不丢失,但也会产生上述 WAL 日志淤积的问题,因此更明智的方法是保证备节点及时恢复。
如果备节点落后主节点 wal_keep_segment 数量的 WAL 日志,则主节点可能会删除备节点仍需要的 WAL 日志,这种情况下会导致流复制中断。
GUC 参数 hot_standby_feedback 用于开启备节点将查询结果反馈给主节点。这种情况下,备节点会定时将最小活跃事务ID(xmin)反馈给主节点,使得主节点在执行 Vacuum 时保留备节点所需的元组。
备节点发送最小活跃事务ID的最大间隔由 GUC 参数 wal_receiver_status_interval 定义。
GUC 参数 max_replication_slots 用于设置主机端的日志复制槽的个数。
用户可以通过 PG_REPLICATION_SLOTS 视图查看复制槽信息。
SELECT * FROM PG_REPLICATION_SLOTS;
主备库延迟
主备库间的延迟主要体现为三个方面:
接收延迟
接收延迟是指备节点接收 WAL 日志到写入 Xlog Buffer 的延迟。
该时间计算方式为: receiver_write_location - sender_sent_location。
落盘延迟
落盘延迟是指备节点接收 WAL 日志到 WAL 日志持久化的延迟。
该时间计算方式为: receiver_flush_location - sender_sent_location。
回放延迟
回放延迟是指备节点接收 WAL 日志到 WAL 日志回放(数据持久化)的延迟。
该时间计算方式为: receiver_replay_location - sender_sent_location。
用户可以通过系统视图 PG_STAT_REPLICATION 查询到上述延迟。
SELECT (receiver_write_location - sender_sent_location) AS receive_delay,
(receiver_flush_location - sender_sent_location) AS flush_delay,
(receiver_replay_location - sender_sent_location) AS rewind_delay
FROM PG_STAT_REPLICATION;
GUC 参数 recovery_min_apply_delay 用于指定备节点回放的延迟时间。该参数仅会影响备节点回放 WAL 日志的延迟,不影响主节点向备节点发送 WAL 日志的时间。
配置流复制集群
前置条件
已安装并启动主节点,备节点已安装未启动。
配置异步流复制
步骤1 修改主节点的 postgresql.conf 配置文件。需要配置的参数说明如下:
wal_level: WAL 日志级别,要开启流复制模式,需要设置为 hot_standby。
max_wal_senders: 指定事务日志发送线程的并发连接最大数量。
max_replication_slots : 指定服务器可以支持的流复制槽数量。
hot_standby: 指定在数据库恢复期间,是否能够连接数据库并执行查询。
wal_keep_segments:Xlog日志文件段数量。设置“pg_xlog”目录下保留事务日志文件的最小数目,备机通过获取主机的日志进行流复制。
synchronous_commit:指定事务同步方式,设置为 off 表示异步流复制。
replconninfoN:设置本端侦听和鉴权的第N个节点信息。
localhost:本地服务器IP地址。
localport:本地端口号,同步日志传输端口。
localservice:主备通讯端口。
remotehost:远程服务器IP地址
remoteport:远程端口号,同步日志传输端口。
remoteheartbeatport:集群心跳端口。
remoteservice:主备通讯端口。
wal_level = hot_standby max_wal_senders = 10 max_replication_slots = 3 hot_standby = on wal_keep_segments = 512 synchronous_commit = off replconninf1 = 'localhost=xxx.xxx.xxx.xxa localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxb remoteport=26001 remoteheartbeatport=26002 remoteservice=26003'
步骤2 在主备节点分别配置 pg_hba.conf 文件,增加以下信息。
host all ${initdb_user} xxx.xxx.xxx.xxa/xx trust
host all ${initdb_user} xxx.xxx.xxx.xxb/xx trust
host all all 0.0.0.0/0 md5
步骤3 应用以上参数配置,并将主节点以 Primary 方式启动。
vb_ctl restart -D data_dir -M primary
步骤4 将主节点的配置文件传输到备节点,并配置 replconninfo1,将 localhost 与 remotehost 的 IP 地址对调。
scp data_dir/pg_hba.conf data_dir/postgresql.conf xxx.xxx.xxx.xxb:/backup_dir
sed -i “/^replconninfo1/creplconninfo1=‘localhost=xxx.xxx.xxx.xxb localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxa remoteport=26001 remoteheartbeatport=26005 remoteservice=26004’” /backup_dir/postgresql.conf
步骤5 在备节点执行 vb_ctl build 完成数据全量同步,build后备库启动。
vb_ctl build -D backup_dir -b full -M standby
用户在主节点可以通过 PG_STAT_REPLICATION 视图查看当前复制情况。
\x
SELECT pid,client_addr,client_port,state,sender_sent_location,receiver_write_location,receiver_flush_location,receiver_replay_location,sync_state FROM PG_STAT_REPLICATION;
回显信息如下:
-[ RECORD 1 ]------------+-------------------------------
pid | 2181
client_addr | xxx.xxx.xxx.xxb
client_port | 5432
state | streaming
sender_sent_location | 0/3000130
receiver_write_location | 0/3000130
receiver_flush_location | 0/3000130
receiver_replay_location | 0/3000130
sync_state | async
配置同步流复制
步骤1 修改主节点的 postgresql.conf 配置文件。需要配置的参数说明如下:
wal_level: WAL 日志级别,要开启流复制模式,需要设置为 hot_standby。
max_wal_senders: 指定事务日志发送线程的并发连接最大数量。
max_replication_slots : 指定服务器可以支持的流复制槽数量。
hot_standby: 指定在数据库恢复期间,是否能够连接数据库并执行查询。
wal_keep_segments:Xlog日志文件段数量。设置“pg_xlog”目录下保留事务日志文件的最小数目,备机通过获取主机的日志进行流复制。
synchronous_commit: 设置当前事务的同步方式。设置为 on 或以上级别支持从库在主库commit后可直接读取已提交的数据。
synchronous_standby_names:同步复制的备机名称列表,每个名称用逗号分隔。
replconninfoN:设置本端侦听和鉴权的第N个节点信息。
localhost:本地服务器IP地址。
localport:本地端口号,同步日志传输端口。
localservice:主备通讯端口。
remotehost:远程服务器IP地址
remoteport:远程端口号,同步日志传输端口。
remoteheartbeatport:集群心跳端口。
remoteservice:主备通讯端口。
wal_level = hot_standby max_wal_senders = 10 max_replication_slots = 3 hot_standby = on wal_keep_segments = 512 synchronous_standby_names = 'node2' replconninf1 = 'localhost=xxx.xxx.xxx.xxa localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxb remoteport=26001 remoteheartbeatport=26002 remoteservice=26003'
步骤2 在主备节点分别配置 pg_hba.conf 文件,增加以下信息。
host all ${initdb_user} xxx.xxx.xxx.xxa/xx trust
host all ${initdb_user} xxx.xxx.xxx.xxb/xx trust
host all all 0.0.0.0/0 md5
步骤3 应用以上参数配置,并将主节点以 Primary 方式启动。
vb_ctl restart -D data_dir -M primary
步骤4 将主节点的配置文件传输到备节点,并配置 replconninfo1,将 localhost 与 remotehost 的 IP 地址对调。
scp data_dir/pg_hba.conf data_dir/postgresql.conf xxx.xxx.xxx.xxb:/backup_dir
sed -i “/^replconninfo1/creplconninfo1=‘localhost=xxx.xxx.xxx.xxb localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxa remoteport=26001 remoteheartbeatport=26005 remoteservice=26004’” /backup_dir/postgresql.conf
步骤5 在备节点执行 vb_ctl build 完成数据全量同步,build 后备库启动。
vb_ctl build -D backup_dir -b full -M standby
用户可以通过 PG_STAT_REPLICATION 视图查看当前复制情况。
\x
SELECT pid,client_addr,client_port,state,sender_sent_location,receiver_write_location,receiver_flush_location,receiver_replay_location,sync_state FROM PG_STAT_REPLICATION;
回显信息如下:
-[ RECORD 1 ]------------+-------------------------------
pid | 19226
client_addr | xxx.xxx.xxx.xxb
client_port | 5432
state | streaming
sender_sent_location | 0/30000D0
receiver_write_location | 0/30000D0
receiver_flush_location | 0/30000D0
receiver_replay_location | 0/30000D0
sync_state | sync
配置级联复制
步骤1 按 配置异步流复制步骤配置主备复制,主备库均已启动。
步骤2 添加复制通道。
在主节点执行以下命令。其中 localhost 指定主节点的 IP 地址,remotehost 指定级联备节点的 IP 地址。
vsql -d postgres -p5432 -c "alter system set replconninfo2 to 'localhost=xxx.xxx.xxx.xxa localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxc remoteport=26001 remoteheartbeatport=26005 remoteservice=26004 iscascade=true’;”
在备节点执行以下命令。其中 localhost 指定备节点的 IP 地址,remotehost 指定级联备节点的 IP 地址。
vsql -d postgres -p5432 -c "alter system set replconninfo2 to 'localhost=xxx.xxx.xxx.xxb localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxc remoteport=26001 remoteheartbeatport=26005 remoteservice=26004 iscascade=true’;”
步骤3 将备节点的配置文件传输到级联备节点。
scp data_dir/pg_hba.conf data_dir/postgresql.conf xxx.xxx.xxx.xxc:/backup_dir
步骤4 配置连接通道。
replconninfo1 的 localhost 指级联备节点的 IP 地址,remotehost 指定主节点的 IP 地址。
replconninto2 的 localhost 指级联备节点的 IP 地址,remotehost 指定备节点的 IP 地址。
sed -i "/^replconninfo1/creplconninfo1='localhost=xxx.xxx.xxx.xxc localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxa remoteport=26001 remoteheartbeatport=26005 remoteservice=26004'" /data_dir/postgresql.conf
sed -i "/^replconninfo2/creplconninfo2='localhost=xxx.xxx.xxx.xxc localport=26001 localheartbeatport=26002 localservice=26003 remotehost=xxx.xxx.xxx.xxb remoteport=26001 remoteheartbeatport=26005 remoteservice=26004'" /data_dir/postgresql.conf
步骤5 在级联备节点执行 vb_ctl build 完成数据全量同步,build后备库启动。
vb_ctl build -D backup_dir -b full -M cascade_standby
用户可以通过 PG_STAT_REPLICATION 视图查看备节点的复制情况。
\x
SELECT pid,client_addr,client_port,state,sender_sent_location,receiver_write_location,receiver_flush_location,receiver_replay_location,sync_state FROM PG_STAT_REPLICATION;
回显信息如下:
-[ RECORD 1 ]------------+-------------------------------
pid | 20431
client_addr | xxx.xxx.xxx.xxc
client_port | 5432
state | streaming
sender_sent_location | 0/3000130
receiver_write_location | 0/3000130
receiver_flush_location | 0/3000130
receiver_replay_location | 0/3000130
sync_state | async