暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

磐维数据库_流复制

原创 磐维数据库 2024-10-31
351

流复制

流复制

之前总有同事很好奇,数据库集群之间是怎么进行数据同步的,然后今天就来简单讲一下磐维数据库的主备之间是怎么进行数据同步的。

数据库通常都允许有一个与主库同步的在线备数据库(主备架构),当主数据库服务器出故障时,备数据库就可以快速提升为主数据库并提供服务,从而实现主数据库服务的高可用。此外,还允许多台数据库服务器同时提供负载均衡服务(也就是一主多备场景)。因为数据库内部记录的是数据,当多台数据库同时提供服务的时候,不会像web服务器那么简单,而是存在着数据的同步等问题。所以通常是一台主数据库提供读写,然后把数据同步到备数据库上,这台备数据库不断的应用从主数据库发来的变化数据。所以这台备数据库不能提供写服务,提供只读服务。

流复制是一种基于预写式日志(wal)的数据同步方式,流复制也被称为物理复制,因为流复制的原理是主节点将wal日志以流的方式发送给备节点,备节点在接收到wal日志后,进行wal日志回放,从而实现主备数据同步。

Wal日志

由于流复制是基于wal日志实现数据同步的,所以我们这里简单讲解一下wal日志的相关内容。

Wal日志文件

Wal是write ahead log的缩写,中文称之为预写式日志,wal日志也被称为xlog,存放在$PGDATA/pg_xlog目录中。预写式日志的概念就是在修改数据之前,必须要把这些修改操作记录到磁盘中,这样后边更新实际数据时,就不需要实时的把数据持久化到文件中去了。

wal命名格式文件名称为16进制的24个字符组成,每8个字符一组,每组的意义如下:

00000001 00000000 00000001

-------- -------- --------

时间线 logid logsed

说明: 这些数字一般情况下是顺序增长使用的(要把所有可用数字都用光也需要非常长的时间),但也存在循环使用的情况。

Wal日志的作用

  1. 故障时,保证数据不丢失
  2. PITR,基于时间点恢复
  3. 流复制
  4. 记录数据库所有的变更和行为

Wal日志的传输

接下来我们通过磐维数据库体系结构图,简单了解下wal相关的进程。

首先wal日志发生在wal buffer缓冲区,然后日志写线程WALwriter会将WAL buffer的内容刷新到磁盘并保存在WAL日志中,确保已提交的事务都被永久记录,不会丢失。

然后walsender在主节点发送wal数据到备节点,备节点的walreceiver和startup进程接收和重放数据,walsender和walreceiver通过一个tcp通讯协议建立连接。

简单描述如下:

当数据库中数据发生变更时:

先要将变更后内容计入wal buffer(日志缓冲区)中,

再将变更后的数据写入data buffer(数据缓冲区);

commit发生时:

wal buffer中数据刷新到磁盘;

数据缓冲区写磁盘推迟;

checkpoint发生时:

将所有data buffer刷新的磁盘。

脏页:在缓冲区,已经被修改但尚未持久化到磁盘的数据页。

如果没有wal日志,那么数据库中将会发生什么? 

首先,当我们在数据库中更新数据时,如果没有wal日志,那么每次更新都会将数据刷到磁盘上,并且这个动作是随机i/o,性能可想而知。

开始流复制

在流复制中,三个进程协同工作,walsender在主节点发送wal数据到备节点,然后备节点启动一个walreceiver和一个startup进程接收和重放数据,walsender和walreceiver通过一个tcp通讯协议建立连接。

开始流复制:

1.启动主节点和备节点

2.备节点启动startup进程

3.备节点启动walreceiver进程

4.walreceiver发送一个连接请求到主节点,如果主节点没有运行,walreceiver会周期性的发送请求

5.当主节点接收到一个请求的请求,就会启动一个walsender进程建立连接

6.walreceiver发送备节点最后的LSN

7.如果备节点的LSN小于主节点的LSN(日志序列号),walsender发送wal数据库,即备节点的LSN到主节点的LSN的wal数据,wal数据存储在主节点的pg_xlog目录下,这个阶段就是备节点追赶主节点的阶段。

8.流复制开始工作。

同步流复制和异步流复制

同步复制 (Quorum):

同步复制要求主服务器在提交事务之前,必须等待至少一定数量的备服务器确认已成功写入相同的数据。这种方式确保了较高的数据一致性,因为事务只有在多个服务器都写入成功后才会提交。如果其中一个备份服务器发生故障,主服务器可能会等待其他备份服务器的确认,从而导致一些性能损失。由于需要等待确认,因此 Quorum 同步复制可能会对性能产生一定的影响,尤其是在网络延迟较大的情况下。

异步复制 (Async):

异步复制允许主服务器提交事务后立即继续处理下一个事务,而不需要等待备份服务器的确认。这种方式可以提供较高的性能,因为主服务器不会被阻塞等待备份服务器的响应。

由于备份服务器的确认并不是实时的,所以存在一定的数据风险。在主服务器发生故障时,可能会丢失尚未传输到备份服务器的数据。异步复制适用于那些对性能要求较高,但对数据一致性要求相对较低的场景。

流复制相关配置参数

wal_level: WAL 日志级别,要开启流复制模式,需要设置为 hot_standby。

max_wal_senders: 指定事务日志发送线程的并发连接最大数量。

max_replication_slots : 指定服务器可以支持的复制槽数量。(物理复制槽和逻辑复制槽都是这个参数控制)

hot_standby: 指定在数据库恢复期间,是否能够连接数据库并执行查询。

wal_keep_segments:Xlog 日志文件段数量。设置“pg_xlog” 目录下保留事务日志文件的最小数目,备机通过获取主机的日志进行流复制。

synchronous_commit:指定事务同步方式,设置为 off 表示异步;on表示同步,默认是on。

流复制。

synchronous_standby_names:同步复制的备机名称列表,每个名称用逗号分隔。当前连接的同步备机是列表中的第一个名称。如果当前同步备机失去连接,则它会立即更换下一个优先级更高的备机,并将此备机的名称放入列表中。

replconninfoN:设置本端侦听和鉴权的第N个节点信息。该参数是用来复制连接信息,用于将主服务器连接到备用服务器上,或将主服务器或备用服务器连接到辅助服务器上。正常集中式集群一主两备部署完成之后,这个参数自动设置连接。

同步和异步设置的区别在于参数:

synchronous_standby_names

当要设置同步流复制,则需要设置synchronous_standby_names不为空,默认synchronous_standby_names为空;

当要设置异步流复制,则需要设置synchronous_commit为off,且synchronous_standby_names必须为空。

流式复制槽

wal日志是会被回收的,不会一直保留,流复制相关的参数wal_keep_segments,就是设置Xlog日志文件段数量。如果此参数设置过小,则在备机请求事务日志时,此事务日志可能已经被产生的新事务日志覆盖,导致请求失败,主备关系断开。

磐维在搭建主备流复制环境后会默认自动创建一个slot_name为对端nodename的物理复制槽,为了防止备库需要的xlog被主库删除或清理。也就是说物理流复制槽用于支撑主备 HA。数据库所需要的物理流复制槽数为备节点加从备的和与主节点之间的比例。例如,假设数据库高可用方案为 1主、1备、1从备,则所需物理流复制槽数为 2。假设数据库的高可用方案为 1主 3备,则所需物理流复制槽数为 3。

流复制相关的sql:

1.查看复制槽

SELECT * FROM pg_replication_slots;

2.查看主备延迟

--主库

select client_addr,sync_state,pg_xlog_location_diff(pg_current_xlog_location(),receiver_replay_location) from pg_stat_replication;

--备库

select now() AS now,

coalesce(pg_last_xact_replay_timestamp(), now()) replay,

extract(EPOCH FROM (now() - coalesce(pg_last_xact_replay_timestamp(), now()))) AS diff;

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论