《postgresql指南--内幕探索》第十一章 流复制

同步流复制是是从9.1版本实现的,可以是一主多从的模式,在postgresql里主节点叫master,备节点叫standby。

主备是基于日志传送的技术实现同步,主节点持续发送wal数据,备节点重放接受到的wal数据。

主要介绍以下几个方面:

  • 流复制如何启动的
  • 主备之间如何传送数据
  • 主节点如何管理多个备节点
  • 主节点如何发现失败的备节点
开始流复制

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

这一章节,我们将探索流复制的start-up顺序,明白这些进程是如何启动,以及如何建立连接。
下图显示了流复制的启动及连接步骤:
在这里插入图片描述
1.启动主节点和备节点
2.备节点启动startup进程
3.备节点启动walreceiver进程
4.walreceiver发送一个连接请求到主节点,如果主节点没有运行,walreceiver会周期性的发送请求
5.当主节点接受到一个连接的请求,就会启动一个walsender进程建立连接
6.walreceiver发送备节点最后的LSN,这个阶段在IT领域叫握手机制
7.如果备机点的LSN小于主节点的LSN,walsender发送wal数据,即从节点的LSN到主节点LSN的wal数据,wal数据由存储在主节点的pg_xlog(10版本以后叫pg_wal)目录下的wal segment提供,这个阶段就是备节点追赶主节点的阶段
8.流复制开始工作

每一个walsender进程在和walreceiver建立连接工作都会有一个合适的状态,以下是可能的状态:
start-up:见上图5~6
catch-up:上图7
streaming:上图8
backup:因为备份发送整个数据库集群的文件,比如pg_basebackup工具

通过 pg_stat_replication视图可以查看:

testdb=# SELECT application_name,state FROM pg_stat_replication;
 application_name |   state
------------------+-----------
 standby1         | streaming
 standby2         | streaming
 pg_basebackup    | backup
(3 rows)

如果备节点在停库长时间后,再启动会发生什么呢?

在9.3以前,如果备节点请求的wal segments在主节点已经被覆盖,那么备节点无法追上主节点,对于这个问题,没有什么可靠的方法,但是把wal_keep_segments参数增大,可以减少这种事件的发生的可能性,这只是一个临时措施。
在9.4以后,这个问题可是使用replication slot来预防。replication slot是一项扩展wal数据发送灵活性的特性,主要用于逻辑复制,并且提供这种问题的解决方法,即暂时回收进程,将包含pg_xlog下未发送的wal segments保存在复制槽中。

流复制如何处理

流复制有两个方面:日志传送和数据同步,日志传送显然其中一个方面,因为流复制是基于日志传送的,不管何时发生写入,主节点都会发送wal到已连接的备节点,同步复制需要数据库同步,主节点和多个备节点同步数据。
为了准确理解流复制的工作原理,我们应该研究一个主节点如何管理多个备节点。为了更容易理解,本节描述了一个主节点和一个备节点的情况,下一节介绍一个主节点和多个备节点的情况

主节点和同步备节点如何通讯的

假设在备节点配置了以下参数

synchronous_standby_names = 'standby1'
hot_standby = off
wal_level = archive

在自动提交模式下,假设后台进程在主节点发出了一条insert操作,后台进程开始一个事务,并且发出一条insert语句,并且立即提交事务,让我们进一步探讨如何完成此次提交:
在这里插入图片描述
1.后台进程通过执行XLogInsert()和 XLogFlush()函数将wal数据写入并刷新到wal segment。
2.walsender进行将写入wal segment的wal数据发送到walreceiver进程。
3.主节点发送wal数据后,后台进程等待从备节点的ACK响应,更确切的说,后台进程执行内部函数SyncRepWaitForLSN()来获取latch锁,并等待锁释放。
4.备节点的walreceiver进程使用write()函数将wal数据写入到wal segment,并且返回ACK响应给walsender。
5.备节点的walreceiver进程使用fsync()函数将wal数据全部刷新到wal segment,并且返回又一个ACK响应给walsengder,通知startup进程wal已经更新。
6.starup进程回放已经写入wal segment的wal数据。
7.walsender进程在接受到ACK响应后释放latch锁,然后,后台进程提交或者终止的操作就完成了。latch释放的时间依赖于参数synchronous_commit,如果参数是on,则在以上第五步接受ACK响应后释放latch,如果设置是remote_write,那么在第四步接受ACK响应后就释放latch。

备节点发送主节点每一个ACK包含以下内容:

  • 已经写入的最新WAL数据的LSN的位置
  • 已经刷新最新的WAL数据的LSN的位置
  • startup进程最新回放wal数据的LSN位置
  • 发送ACK的时间戳

walreceiver不仅在写入和刷新的WAL数据的时候发送ACK响应,而且还定期作为备节点的心跳发送ACK响应。因此,主节点始终掌握所有备节点的状态。

通过以下查询可以看到相关LSN的信息:

testdb=# SELECT application_name AS host,
        write_location AS write_LSN, flush_location AS flush_LSN, 
        replay_location AS replay_LSN FROM pg_stat_replication;

   host   | write_lsn | flush_lsn | replay_lsn 
----------+-----------+-----------+------------
 standby1 | 0/5000280 | 0/5000280 | 0/5000280
 standby2 | 0/5000280 | 0/5000280 | 0/5000280
(2 rows)

心跳发送间隔通过wal_receiver_status_interval设置,默认10秒。

当失败发生时的行为反应

本小节,描述同步流复制的备节点故障时,主节点是如何的表现,以及如何处理这种情况。
即使同步流复制的备节点发生故障,并且不能够给主节点返回ACK响应,主节点也会继续等待ACK响应。因此,在主节点运行的事物无法提交,后续的查询也无法执行。换句话说,主节点所有的操作都是停止的。(流复制不支持由于超时而自动转到异步流复制的函数)

有两种方法避免这种情况的发生,其中之一就是提供多台备节点来提高系统的可用性,另一个就是通过手动执行以下步骤从同步流复制转换到异步流复制:
1.设置以下参数为空串

synchronous_standby_names = ''

2.执行reload命令重载配置文件

pg_ctl -D $PGDATA reload

以上操作对已经连接的客户端没有影响,主节点会继续处理所有连接的session的事物。

管理多个备节点

主节点提供所有备节点的sync_priority和sync_state,并依靠这些值来处理备节点。主节点即使管理一个节点也会也会提供这些值,在上一节中没有提到这一点。
sync_priority表示在同步模式下备节点的优先级,是一个固定值。越小的值优先级越高,0表示异步模式,备节点的优先级按synchronous_standby_names顺序列出,例如,以下配置中standy1和standy2的优先级分别是1和2。

synchronous_standby_names = 'standby1, standby2'

此参数未列出的的备节点是异步模式,优先级的值为0。
sync_state表示备节点的状态,这个值根据所有备节点的运行状态以及优先级发生变化。

  • Sync是所有同步模式下备节点最高优先级。
  • Potential是所有备节点中第二高的优先级级别,如果最高优先级的备节点故障,那么这个节点会代替故障节点变为最高优先级的备节点。
  • async异步模式的固定值,主节点以potential一样的看待这个异步备节点,但是sync_state不会是sync和potential状态。

可以通过以下视图查看这两个值:

testdb=# SELECT application_name AS host, 
         sync_priority, sync_state FROM pg_stat_replication;
   host   | sync_priority | sync_state
----------+---------------+------------
 standby1 |             1 | sync
 standby2 |             2 | potential
(2 rows)
主如何管理多个备节点

主节点会等待单个同步模式下的备节点ACK响应,换句话说,主节点只确认同步流复制的写和刷新的wal数据。因此,流复制仅仅确定同步流复制备节点与主节点处于一致和同步状态。

下图给出了Potential备服务器的ACK响应比主备机早返回的情况。在那里,主服务器没有完成当前事务的提交操作,并继续等待主服务器的ACK响应。然后,当接收到主进程的响应时,后端进程释放锁存器并完成当前事务处理。
在这里插入图片描述
standby1和standby2的sync_state分别为’sync’和’potential’。尽管从潜在的备用服务器接收到ACK响应,主进程的后端进程继续等待同步备用服务器的ACK响应。(2)主进程的后端进程释放锁存器,完成当前事务处理。

在相反的情况下(即主服务器的ACK响应比潜在服务器早返回),主服务器立即完成当前事务的提交操作,而不确保潜在备用服务器是否写和刷新WAL数据。

故障发生时的行为

同样,我们来看下主服务器在备用服务器失败时的行为。

当potential或异步备用服务器发生故障时,主服务器终止连接到故障备用服务器的walsender进程,并继续所有处理。换句话说,主服务器的事务处理不会受到任何一种备用服务器故障的影响。

当同步备用服务器发生故障时,主服务器终止连接到故障备用服务器的walsender进程,并用最高优先级的潜在备用服务器替换同步备用服务器。见图11.4。与上面描述的故障相反,从故障点到替换同步备用时,主服务器上的查询处理将暂停。(因此,备用服务器的故障检测是提高复制系统可用性的一个非常重要的功能。故障检测将在下一节中描述。)

在这里插入图片描述
如果一个或多个备用服务器以同步模式运行,则主服务器始终只有一个同步备用服务器,同步备用服务器始终与主服务器处于一致同步状态。

检测备用服务器的故障

流复制使用两种常见的故障检测程序,而且不需要任何特殊的硬件。

  1. 备用服务器进程故障检测:当检测到walsender和walreceiver之间的连接断开时,主服务器立即确定备用服务器或walreceiver进程故障。当一个low level网络函数在写或读walreceiver的套接字时返回一个错误,主函数也会立即判断出备用服务器进程故障了。

  2. 硬件和网络的故障检测:如果walreceiver在wal_sender_timeout参数设置的时间内(默认为60秒)没有返回任何值,则主服务器判定备服务器故障。与上述故障对比,即使备节点由于故障长时间没有任何响应,也需要wal_sender_timeout这么久的时间确认备节点故障.

根据故障类型,通常可以在故障和检测之间会有时间差,特别是,在同步流复制中发生了一种类型的故障,主节点的所有事务处理将停止,直到探测到备节点故障,即使多个potential备节点在运行.


本文翻译整理自:https://www.interdb.jp/pg/pgsql11.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL是一种开源关系型数据库管理系统,具有高度可扩展性、安全性和可靠性,是许多企业和应用程序的首选数据库。在本指南中,我们将深入探讨PostgreSQL的内部结构和运作方式,以帮助您更好地理解和优化您的数据库。 1. PostgreSQL架构 PostgreSQL的架构由多个进程组成,每个进程都具有特定的任务。以下是PostgreSQL的主要组件: - 后台进程:管理数据库文件、完成备份和恢复操作以及其他管理任务。 - 前台进程:处理客户端请求、执行SQL查询和更新操作。 - 共享缓存:存储常用表和索引的数据块,以提高查询性能。 - 数据文件:存储数据库表和索引的数据。 PostgreSQL的体系结构非常灵活,可以在不同的硬件和操作系统上运行,并且可以根据需要进行配置。 2. 数据库对象 PostgreSQL支持多种类型的数据库对象,包括表、视图、索引、函数、存储过程和触发器等。这些对象可以存储在不同的命名空间中,例如公共命名空间、用户命名空间和模式命名空间。每个对象都有一个唯一的OID(对象标识符),用于在系统中标识它。 3. 数据库事务 PostgreSQL使用多版本并发控制(MVCC)来管理事务,这意味着每个事务都可以看到数据库的某个历史状态。当一个事务更新数据时,它实际上只是在数据库中创建了一个新版本的数据,而不是直接更新现有数据。这使得多个事务可以同时读取和更新相同的数据,而不会相互干扰。 4. 查询处理 PostgreSQL使用优化器来处理SQL查询,选择最有效的执行计划。优化器考虑了多种因素,包括查询条件、表大小、索引可用性和查询类型等。一旦找到最佳执行计划,PostgreSQL就使用执行器执行查询并返回结果。 5. 数据库安全 PostgreSQL提供多种安全功能,包括用户认证、访问控制和加密通信。用户可以通过用户名和密码进行身份验证,并根据需要进行授权。管理员可以使用访问控制列表(ACL)来限制用户对特定数据库对象的访问权限。此外,PostgreSQL还支持SSL和TLS协议来加密数据传输。 总结 PostgreSQL是一个功能强大、高度可扩展和安全的关系型数据库管理系统。它使用多版本并发控制来管理事务,具有灵活的架构和优化器来处理SQL查询,同时提供多种安全功能来保护数据安全。通过深入了解PostgreSQL的内部结构和运作方式,您可以更好地优化和管理您的数据库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值