开发者学堂课程【PostgreSQL快速入门:PostgreSQL 流复制搭建主从环境,同步和异步的解释,压力测试,主从角色切换 】学习笔记与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/16/detail/94
PostgreSQL 流复制搭建主从环境,同步和异步的解释,压力测试,主从角色切换
内容介绍
一、 8 PostgreSQL 流复制协议搭建主从环境
二、 同步和异步的解释
三、 流复制 hot _ standby 演示
本节课讲解 Postgre 数据库的流复制。上节课讲解了数据库物理备份时用到了一个工具,此工具是通过数据库的流复制协议来备份数据库的物理文件,以此达到数据库备份物理文件的目的。
一、8 PostgreSQL 流复制协议搭建主从环境
首先,在 PostgreSQL 文档当中, 有一专门讲解协议的是Frontend / Backend Protocol ,流复制协议存在一些要求,比如备份 START_REPLICATION ,
通过流复制协议向数据库发送一个指令,就会将数据文件拷贝出来,通过流复制的连接将其传输到流出段的一个节点; BASE BACKUP 工具用来做基础备份。
数据库流复制
9.0开始支持1+ n 的异步流复制,异步流复制指的是事务在主节点提交时是异步的,1+ n 是指1个主节点, n 个流复制的内容。
9.1开始支持1+1+ n 的同步和异步流复制,异步是指在主节点提交事务时,异步的节点接受到的地方与其没有关系,而同步是有关系的,比如说此事务是同步事务,事务所产生的 xlog 要已经在同步节点中复制完成,这样说明事务允许提交成功,此事务在提交时会处于等待的状态,直到等到同步 Standby 节点收到这笔 xlog 的信息之后,反馈到主节点,主节点返回给程序,说明事务已经提交成功。1+1+ n 指一个主节点,一个同步 Standby 节点, n 指 n 个异步节点, 当此主节点同步的 Standby 节点挂掉之后, n 里就会选举出一个,它就变成了同步节点,相当于最终是1+1+ n 的状态,所有的节点还是通过一个主节点复制 xlog 。
9.2开始支持级联流复制,级联复制指可以一个主节点,后面还可以挂 Standby 节点,9.1和9.0相当于所有的 Standby 节点都是通过单一主节点去同步 xlog 数据。9.2的级联复制指比如 A 是主节点, B 是 Standby 节点,C 也是 Standby 节点,但是B是直接连 A 的主节点, C 是通过 B 取数据,也就是说 B 既从 A 里接收 xlog ,也向 C 发送 xlog 。
9.3开始支持跨平台的流复制协议(目前可用于接收 xlog ),不同的平台都是可以使用此协议来拷贝数据。
9.3开始流复制协议增加了时间线文件传输的协议,支持自动切换时间线。
二、同步和异步的解释
如图是异步流复制的原理,虚线的左上是 Standby ,虚线的右下是 Primary 。
Standby 中存在一个 wal receiver 进程, Standby 是一个一直处于恢复状态的数据库, Primary 是一个运行的数据库,是生产数据库,要进行恢复或运行是通过 pg _ controdate 这条命令决定的,指定的一个 DATA 目录。
比如此时是 in production 状态,表示一个生产库,此台是 Standby ,模式为 in archive recovery ,表示一个 Standby 数据库,或是正在恢复的状态,当前状态为恢复 0 的,是一个流复制,此时有一个 receiver 的进程一直在接收。
有一个主节点是 sender 键,一直向172.16.3.39发送 xlog 信息,只要有 xlog 产生,就会持续不断地发送给172.16.3.39,当其接收后,会进行 recover 。如果没有流复制的连接,数据恢复会到 archlog 里,是前面所讲解的配置 restore _ command , 这是第一个是在归档里,若归档里取不到数据时,就会到本地 xlog 中( pg _ xlog ),第一步是在归档里取,通过归档命令 / ssd4 / pg 93/arch /20131299/% f % p 取需要的 xlog ,若是取完或是取不到,就在 pg _ xlog 中取,如果此处还不存在更新的数据,查找 restore _ conninfo 文件中是否配备有 primary _ conninfo = ”命令,如配备则会主动生成一个 wal receiver 进程,向 Primary 节点发起一个请求,在此处实时数据,要进行流复制协议, wal receiver 与 wal sender 两者需要进行一个沟通, postmaster 是一个监听进程,向它发起一个请求,会 fork 一个 wal sender 进程,此进程( replica 172.16.3.39<56652>)就会不断向 wal receiver 进程中发送 xlog 信息,是一个数据流的过程。
在主节点这里,应用程序做了一些操作后,会产生一些 WAL buffer ,专门有一个 wal writer 将 buffer 写进 XLOG 中, sender 进程 从 XLOG 文件中读而非 WAL buffer 中,因为只有写在文件中的数据才确保安全,切记 sender 进程是从 xlog 文件中读,读完发送到 Standby 节点。 startup process 取到 xlog 后,会一直做 recover,比如对数据做了变更,接收到 xlog 后,会将其恢复到对应文件中。
对应参数:
Primary
max _ wal _senders 做流复制时,主节点需要配备,一定要配备的有 wal _ level 、 hot standby ,这样才能建立起 hot _ standby 节点,其次要配备的是归档模式,当 standby 节点因为网络中断等原因导致长时间没有与主节点发生交互时, xlog 文件会轮巡,不会保留。存在一个 keep _ segment,是指最多保留256个文件,当达到256个文件之后,旧文件可能会被覆盖掉。
如果没有归档的情况,只能凭借 in legfile segments ,16 MB each ;0 disables 里的 xlog 文件取,当文件被覆盖掉,则永远追不到主节点,会一直处于等待状态,
所需要的 xlog 在主节点中已找不到,只能在归档中取,如果配备归档,则直接在归档中取。
配置归档命令, bin / date 命令是一个伪命令,没有任何用处,真正的归档是将 xlog 文件拷贝到一个地方。
还要配备的是 wal _senders ,表示允许多少个流复制协议连接,如配置 hot _ standby ,至少配置成1,自然允许一个连接,32表示同时有32个流复制节点。
wal _ keep _ segment _256已经讲解过,因为文件在 pg _ xlog 目录中是轮巡的,所以需配置稍微大的数量,不能超出目录的大小,会导致主节点目录删除。
Master 节点也需要配置,比如做同步流复制时,需要指定同步 standby 节点名称,如名称为 all ,则全部都可以放到 standby 节点中;如 standby 节点有三个,但其中两个是在另外的 IDC ,所以同步流复制点放在本地 IDC 中,此处可以配备 application _ name ,如其被指定为 A ,就配备 A ,另外两个 IDC 的 standby 节点称为 B 和 C ,则 B 和 C 不用配备。
hot _ standby 节点需要打开才能做线上查询,若不打开则一直处于恢复状态,不允许查询。
max _ standby _archive _delay , max _ standby _ streaming _delay 时间调整的长,在查询时,如正在查询 A 表,主节点可能已经将此表删除, standby 节点已经接收到,如做申请,则 A 表会被删除,正在查询的 A 表与申请就发生冲突,冲突的时长就是等待的时长,最多等待300秒,如超过300秒冲突仍然存在,就将正在查询的 A 表 sql 语句删除掉,这就是解决冲突的一个时长,允许有300秒解决冲突,如果仍然不断开,就将其删除,因为还要进行恢复,否则会与主节点延迟300秒。
wal _ receiver _ status _ interval ,每个一秒钟向主节点发送统计状态信息,已经接收到哪里或申请到哪里,此一秒钟是指在没有接收到任何数据情况下时也会发送,当接收到一笔数据时,也会向其发送,也就是说这是一个最长的时间,最短的时间与接收到的频率有关系,比如每0.1毫秒发送数据,间隔会变成0.1毫秒,因为每接收到一笔数据后都会反馈给主节点。 hot _ standby _ feedback _ on 是指已经发送冲突后,将冲突反馈给主节点,打开就会反馈,不打开则不会反馈。
同步流复制原理,与异步流复制的进程是完全相同的,
但在主节点处多一个队列,队列记录了从 standby 节点反馈到的东西,如接收到何处、申请到何处、 xlog 的虚拟地址、恢复到何处;队列中存储了事务状态信息,比如某事务的事务号为1000, 接收反馈给主节点, xlog 已经接收到1001,则表示1000的事务可以提交。
在主节点里,有一个队列记录了事务,事务在排队等待同步流复制是否接收到了部分事务信息,如接收到,则在队列中的事务信息只要小于事务号的信息都可以反馈给事务应用程序,也将被提交。
对应参数:
Primary
同步流复制需要多配备的是 synchronous _ standby _ names 。
三、流复制 hot _ standby 演示
首先,此节点是主节点,先有主节点后有备节点,端口是5432,监听的是0.0.0.0。第一步进行规划,由于没有表空间所以没有其他的目录。
如何建立备节点?
首先安装一个软件,主节点编译的参数是pg _ config —— configu,在讲解数据库安装时涉及到,配置要求与图中完全相同,在编译时一定与主节点一致;如主节点是使用 gmake word 安装,那么也须使用 gmake word ,能确保在节点中创建的文件在 iso 文件中已经创建完成。
更为方便的是直接将图中安装的目录进行打包,拷贝到 standby 节点中,此处是进行直接编译,与其完全相同。
编译完成后,其次是配置主库, postgresql . conf
, wal _ level 配置成hot _ standby ,还需要配置的是 archive _ command ,如下图前两个是可选的,在生产环境中将它打开。
max _ wal _ senders 配置成32, wal _ keep _ segnents 确保有256个文件存在,演示配置的为同步流复制节点,将其配置成 * ,所有节点都成为候选同步流复制节点,将 hot _ standby 打开,如图是 standby 配置,在切换时两个都将打开,互不影响。
接下里需要新建一个角色,角色用于流复制,此处使用了 replica 角色,允许从3.33、3.39连接,replication 协议通过用户连接,将角色的密码换成 drop role ,create role replica允许其登录 ,如下图所示是其的角色,密码叫做 replica 。
配置密码文件,将密码改成 replica ,同时将密码文件改成400,在主节点处也可以对密码进行修改,优点是做角色切换时两个密码都存在, ip 地址来源于172.16.3.38(主节点的 ip 地址),此 ip 地址可以做漂移。
下一步骤使用 pg _ basebackup 创建备库基础备份,由于建立 standby 节点,所以使用 plain 模式,将其备份到 $ PGDATE 中,确保结构一致,下图是备份的结果。
将 recovery 文件重新命名为 conf ,此文件已经写完成,未写完成可进行拷贝,说明这是一个 standby 节点,还可以继续进行恢复。需要将时间线配置成 latest ,无论是否做过角色切换,都将跟从;还需要配置 primary _ conninfo ,主节点的 ip 为172.16.3.38,端口为5432,用户名为 replica ,由此便可做恢复,相当于备节点已经配置完成。
如果将下图数据库停止,要运行事务就不会被允许,
synchronous _ commit 关闭,则不需要同步提交,这笔事务与同步流复制没有关系,当前是同步流复制节点,接收到这笔信息之后才会被打开,事务才算结束,同步流复制的数据已经被复制过;对于重要事务,可以将 synchronous _ commit 打开。
同步流复制的状态, ip 为172.16.3.39, sync _ priority 为1,当前只有一个流复制节点,所以只能看到一条记录;如有多个流复制节点,则只有一个这一个为流复制节点,其余的节点都为异步流复制节点。如果此处不打开同步流复制,将其停止或改掉再进行重新加载和查看,查看的结果为异步流复制节点,也就是说,将数据库关闭后向里边写数据也没有影响,也查看不到 replication 的状态;将其再次打开查看状态,其状态立马呈现。
状态信息,一个函数是 xlog 已经发送到何处,另一个函数是用来查看当前数据库,例如当前插入到何处,流复制节点也已经复制到此处,表示流复制节点和主节点是完全同步的, xlog 数据完全接收到;write表示写入 buffer, flush 表示将 wal 中的 buffer 已经写入日志文件中, replay 表示这部分数据已经恢复。
下一步使用 pgbench 进行压力测试,查看流复制统计信息表 pg _ stat _ replication 。
使用优化的测试模型,模型中包含用户表、用户会话表,用户跟踪记录、用户退出记录,向里边插入两百万条测试数据,会话表中也插入两百万条测试数据,随后创建两个主键;此模型是模拟用户登陆,登陆时根据用户 ID 查询用户信息,同时插入登陆记录到 user _ login _ rec 日志表;如是退出,则缺少了查询用户信息,而是插入退出记录到 user _ logout _ rec 日志表,再更新 user _ session 表最后一次退出时间和在线时长字段,通过调用函数达到压力测试,函数就是指定范围调研用户登陆,上方是两百万条数据,下方是 pgbench- M prepared - n - r - f ,/ test .sql - h 127.0.0.1 - p 5432 - U postgre postgres ,指定16个连接,压30秒,查询状态时,主节点一直在插入,备节点在接收,接收和插入有一点差别但是影响甚小,如是同步节点则没有任何差别,30秒时间结束,完全达到同步,延迟时间非常短,测试出的压力结果为30000 tps ,包含一个选择、插入和更新,再有异步节点的情况下,事务会达到此数据;
改成同步流复制, 使用 remote _ write 后,打开后进行重新加载进行压力测试,如图是反馈的数据,会与主节点当前的插入有一定的延迟,反馈的速度没有插入的速度快,但是事务会存在一个等待的状态。
性能会下降很多是因为开启了了同步 remote _ write,如将其关闭,测试结果还是与之前相同,原因是相当于在主节点发生了完全的改变。即使是异步流复制节点,压力测试结果还是与之相同,原因是瓶颈不是在同步流复制,结果差别不大,只是千的基础;只有将 synchronous _ commit 关闭,性能提升才会非常明显。
角色切换测试,33是主库,39是备库,将主节点数据库关闭,将同步流复制节点改为异步流复制节点,在其他案例中不需要,关闭之后将 ip 删除,激活数据库,
时间线已经切换,将38的 ip 漂移,再将原来主节点 recovery 文件改成 conf 之前被称为 done ,表示已经恢复结束,激活完成,成为可读可写的数据库,现在处于一种生产运行模式中,原来的主节点变为一个备节点,从39 处接收数据,处于 recovery 模式。