天天看点

PostgreSQL复制原理及高可用集群 ——朱贤文

内容简要:

一、PostgreSQL高可用

二、PostgreSQL流复制

三、PostgreSQL逻辑复制

四、PostgreSQL高可用集群

(一)PostgreSQL高可用的种类

l  常用的高可用架构及基本原理包括:

1)共享存储;

2)流复制;

3)逻辑复制;

1.  共享存储:

共享存储是所用的存储空间相同,但实例运行放在不同的节点上。

示意图如下:

PostgreSQL复制原理及高可用集群 ——朱贤文

当在正常工作状态,主节点在计算机上启动,但是计算机里文件系统是接在SAN存储上,SAN存储同时也可以连接到备用节点,正常情况下主节点对共享存储进行读写,对外提供业务和服务。

PostgreSQL复制原理及高可用集群 ——朱贤文

如上图所示,当主节点故障时,会由备用节点接管数据库,重新启动实例做回滚。这种架构底层用到专门的存储叫SAN,它的好处是数据放在共享存储上,当主节点坏掉,从节点启动后会沿着主节点坏掉的时间点进行回滚,回滚到最后一次切换,经过Commit和Rollback,最后把数据库打开对外提供服务,不会丢数据。

这对数据可靠性要求较高的行业,是比较好的方案。

2.流复制

在Oracle里面,可以用对等的DataGate概念对应PostgreSQL的流复制。根据数据流,每一个数据流Commit的时候会复制下去。

流复制分为:同步流复制和异步流复制。

根据用户不同的配置情况,在流复制里面可以搭建很多节。主节点上面,对外正常提供读写服务,然后通过流复制,可以挂一个或者多个从节点。在从节点上面,可以根据业务场景的需要,对高可用的需要或者负载均衡的需要,搭建一个或者多个二级从节点,根据业务需求,第二级从节点上再往后可以搭建第三、第四、第五等多级从节点。

PostgreSQL复制原理及高可用集群 ——朱贤文

流复制特点总结:

• 主节点可以有多个从节点;

• 从节点上还可以挂载从节点;

• 从节点个数没有明确限制,层级无限制;

• 主从间可以同步复制、可以一步复制,也可以同步一步混合复制。

3.逻辑复制

逻辑复制是数据库内部数据块的具体操作,比如Insert、Delete操作解析出来,经过发布节点Sender进程向外发布之后,然后订阅节点对订阅 Publisher定义的指定名字进行搜索表的操作。

PostgreSQL复制原理及高可用集群 ——朱贤文

逻辑复制特点总结:

• 所有节点都是对等关系,都可读写;

• 所有节点可以是发布节点,订阅节点,也可以同时是发布节点和订阅节点。

逻辑复制和流复制之间的差别是:

• 流复制里只有一个主节点,可以挂很多从节点。逻辑复制里所有的节点都是对等的主节点,都可以提供对外读写操作。

• 逻辑复制实际是从逻辑上把 SQL解析出来,到其他订阅节点进行重放,相当于SQL的重新回放。流复制发布的数据是更改的数据块。

PostgreSQL复制原理及高可用集群 ——朱贤文

PostgreSQL数据库流复制基本原理

如上图所示,从写程序流程来看基本原理,首先启动Postmaster进程,系统正常运行,如果客户端(WalReciver)进行流复制,启动之后客户端会连到Master,Master收到流复制信号会Fork一个指定层,指定层启动WalSender,后面是相应的流程,根据系统ID或用户网段在相应时间内完成。

计算要从什么时间点取什么数据呢?

系统在有SendTimeLineHistory的情况下会选择优先使用,否则会去做一些其他操作。通过CreateReplicationSlot开始找复制的时间点拷贝数据,SendPhysicak收到私人信息后会进行写操作,整个流程形成一个大循环。

PostgreSQL复制原理及高可用集群 ——朱贤文

数据库的Commit操作之后,Execute执行器将要改的脏数据写到WAL中,通过Sender发送到从数据库,从数据库这端对应的Receiver写到WAL日志里面,WAL再到数据库文件Date File Heaps,写到数据库之后,外面的查询执行器就可以进行取数据,以上就是流复制的大致流程。

PostgreSQL复制原理及高可用集群 ——朱贤文

上方为流复制环境搭建实现过程,用 pg_basebackup命令搭建,用 help关键的参数,这里“-d”是拷贝过来的数据库要放在哪个目录,“-f”是用什么样子的格式拷过来,“p|t”t是纯文本,p是裸数据,“-r”是以什么样子的速率来拷,可以限制它的速度等等。

下面举一个简单的例子:

PostgreSQL复制原理及高可用集群 ——朱贤文

首先定义到“data/appdb”目录,用basebackup命令,从主节点“192.168.56.3”通过Replicator用户,把“d”指定到这里,“-R -Fp -Xs –P”,“-R”命令会创建一个从节点,同时自动创建Replicator文件。

如果是设置同步复制,通过synchronous_standby_names控制同步复制。例如部署一套系统在两个数据中心里面,这两个数据中心通过FIRST 2 (application1,application2,application3)的方式Commit成功了,认为整个系统成功。

l  Synchronous_satandby_names=FIRST 2(application1, application2, application3)

PostgreSQL复制原理及高可用集群 ——朱贤文

Application1与Application2在同一个数据中心,因此主节点Commit的时候要保证Application1与Application2两个节点同时成功。

 FIRST 2是定义三个Application,定义前面两个成功则认为提交成功。用特性限制服务器可以限制整个架构,例如同城用一个Commit或者异地用一个Commit,可根据实际情况进行定义。

l  Synchronous_satandby_names=ANY 2(application1, application2, application3)

PostgreSQL复制原理及高可用集群 ——朱贤文

一个数据库三个 Slave,只需要Application1/2/3其中任意两个Commit成功即可。

l  Synchronous_commit=off

同步复制有几个点来控制具体行为,这些行为会决定Commit本身的性能与可靠性等。如下图所示:

PostgreSQL复制原理及高可用集群 ——朱贤文

首先在主节点上面Commit,Executer直接写内存,相当于从WAL buffer里去写WAL文件,这个过程只确认WAL buffer里面的东西是否写到文件系统中,这个时候相当于关闭本地写WAL文件的过程,具有一定风险,但是Commit返回会非常快。

l  Synchronous_commit=local

PostgreSQL复制原理及高可用集群 ——朱贤文

synchronous_commit=local表示Commit的时候将数据写到本地的WAL文件里,数据库是写到本地提交。虽然是同步,但Local的可靠性比 Off要高一点,能保证主节点上面数据写入到日志。

l  Synchronous_commit=on(default)

PostgreSQL复制原理及高可用集群 ——朱贤文

还有一个选项synchronous_commit=on(default),On表示Commit完成。Commit之后写到WAL文件中,然后通过 WAL Sender发送出去,从端接收数据,同时将数据写到从端的WAL filed中,这个是默认的级别,相当于本地的WAL与从端的WAL里都有这个数据,数据就是安全的。

l  Synchronous_commit=remote_write

PostgreSQL复制原理及高可用集群 ——朱贤文

Sender发送数据,Reserve收到后向文件系统中写数据,把数据提交给文件系统的缓存,不会把数据从缓存中刷到磁盘内。相当于对端那个服务器,这个返回非常快,因为当数据Flash到WAL文件时它已经返回,但只能保证本地这一份数据的可靠性,无法保证远端那一份数据的可靠性,有可能会导致数据丢失。

如果遇到一些极端情况,例如Commit恰好在中间某处,Reserve往下写但还没有写到WAL文件之前,如果这个时候阻断断电,从端没有把数据切换,将数据库切换成组,就可能会存在一定的问题。

l  synchronous_commit = remote_apply

数据写到WAL文件中,从端数据库把数据Apply到远端的数据库了,此时两端数据库里面的内容完全一致。如下图所示:

PostgreSQL复制原理及高可用集群 ——朱贤文

Remote_play是复制性能最低的一种,一旦数据Remote_play到远端的数据库之后,主端有什么数据,从端就一定能看见什么样的数据。

但是在Synchronous_commit=on(default)默认的情况下,数据则不一定相同。因为主端写的压力很大,只会将从端写到WAL中。由于是先改的脏数据再去改数据,因此主端可以查,但在从端因为做 Replay的时候速度是串行的,Replay的性能不一定能跟上,因此这个时候到从端去查数据不一定能够查到,但这并不意味着数据丢失,而是因为数据仍在WAL中,还没恢复到数据库里。

1.逻辑复制的工作原理

PostgreSQL复制原理及高可用集群 ——朱贤文

逻辑复制有个概念是发布者和订阅者,主端如果要通过逻辑复制,首先要进行定义,配置文件里面有一个日志级别,要把它设置为Logical之后的话就可以去定义Publisher,传输通道是用Sender or Reserve机制。

2.逻辑复制搭建

PostgreSQL复制原理及高可用集群 ——朱贤文

首先在发布端确保Level(此处指Logical),确保逻辑复制可以正常进行。通过PG_hba设置用户所需要的权限,设置完成之后可以到数据库中去定义Publication。例如定Publication的名字为“insert _only”,然后FOR TABLE叫“mydata”,table给它定义一个权限WITH (publish = 'insert');,此时,这张表只会去做发布Insert、Update、Delete这样的操作,不会往外发送,用户可以通过Publish关键字里面定义多个行为。

当命令执行完之后,Population也完成,接着设置订阅端,通过CREATE SUBSCRIPTION mysub,同样要跟连接串定义,例如是主机、端口、用户、数据库等,有了连接串之后,Publication用定义对应的名字,这样在主端做什么事情,从端马上可以得到反馈。

四、PostgreSQL ECOX高可用集群

ECOX是一个专门为PostgreSQL流复制设计的高可用集群。

PostgreSQL复制原理及高可用集群 ——朱贤文

如上图所示,ECOX有一个仲裁集群,它避免单点故障导致误判。一个仲裁集群可以管N个PG集群,在PG集群内部的主从是自动切换的。

PostgreSQL复制原理及高可用集群 ——朱贤文

上图为ECOX的基本原理例子,有0、1、2三个节点,可以看到节点的IP与端口是否在线,Master、Commaster与Last Master的详情。

这个系统目前支持PostgreSQL,Hunghu DB以及KingBase新版本。

PostgreSQL复制原理及高可用集群 ——朱贤文

我们也将ECOX做到自己的数据云平台“鸿鹄彩云”中,支持PostgreSQL、Greenplum,给业务带来了很大的帮助。