PG学习笔记(1)—— 主从复制:流复制

闲云野鹤,乡夫俗子,不过一隅静土。

背景

PostgreSQL 9.1之前,主从复制传输以WAL日志文件为单位,主库写完WAL日志后再传输给从库,导致主从延迟较大。基于这种情况,PostgreSQL 9.1引入主从流复制,以WAL日志的record为传输单位,从库及时同步主库数据,并且应用每个WAL record,因此能做到同步复制。另外实现了Hot Standby,从库在应用WAL record的同事能够提供制度服务。

架构

PG主从流复制的核心有三个进程构成:

  • walsender:用于主库发送WAL日志记录到从库;
  • walreceiver:用于从库接收主库的WAL日志记录;
  • startup:用于从库apply日志。

流复制的启动

1.启动过程

  1. 启动主从服务器;
  2. 从库节点启动startup进程;
  3. 从库节点启动walreceiver进程;
  4. walreceiver进程向主库节点发送连接请求,如果主库尚未启动,walreceiver会定期重发该请求;
  5. 当主节点收到连接请求时,将启动walsender进程,并建立walsender和walreceiver之间的TCP连接;
  6. walreceiver发送从库节点最新的LSN;
  7. 如果从库最新的LSN小于主库最新LSN,即落后。walsender会将前一个LSN到后一个LSN之间的wal数据发送到walreceiver;
  8. 流复制开始工作。

2.walsender状态

通过pg_stat_replication试图可以查看所有运行的walsender状态

walsender进程可能的状态如下

  • start-up
  • catch-up
  • streaming
  • backup

3。从库节点长期停机启动

  • PostgreSQL 9.4之前,如果从库节点请求的WAL段在主库节点已经被覆盖,那么备份节点将无法追上主节点。暂时没有解决方案,需要把wal_keep_segments参数调大;
  • PostgreSQL 9.4之后,使用复制槽(replication)来预防——通过暂停walreceiver进程,将含有未发送wal段的pg_xlog保存在复制槽中。复制槽可以提供wal数据发送的灵活性,主要用于逻辑复制。

流复制过程

流复制包括两个方面:日志传输和数据同步

  • 流复制基于日志传输,主节点会在写入日志记录时,将WAL数据发送到已连接的从库节点;
  • 同步复制需要数据库同步,主库节点和多个从库节点通信,从而同步整个数据库集群。

1.主从之间的通信

假设在从库节点处于同步模式,hot_standby参数已禁用、wal_level为‘archive’,即主库配以下参数:

synchronous_standby_names = 'standby1'
hot_standby = off
wal_level = archive

假设后台进程在自动提交模式下在主节点发出一条insert语句。后台进程启动事务、发出一条insert语句、然后立即提交事务。分析如下:

  1. 后台进程执行XLogInsert()和XLogFlush()函数,将wal数据写入缓存并flush到wal段文件;
  2. walsender将写入的wal段文件的wal数据发送到walreceiver;
  3. 主库节点发送wal数据后,后端进程继续等待来自从库节点的ACK响应。即后台进程执行内部函数SyncRepWaitForLSN()来获取latch,并等待释放;
  4. walreceiver通过write()函数将接收到的wal数据写入从库节点的wal缓存,并且返回ACK响应给walsender;
  5. walreceiver通过fsync()函数将wal数据全部flush到wal段文件,并且再返回一个ACK响应给walsender,通知startup进程wal相关数据已更新;
  6. startup进程应用写入wal段文件的wal数据;
  7. walsender在接受到ACK响应后释放latch,然后后端进程完成commit或abort动作。latch释放的时间取决于synchronous_commit:如果参数是on,则在步骤(5)接收ACK响应后释放latch;如果是remote_wirte,那么在步骤(4)接收ACK就释放latch,

2.ACK响应内容

ACK响应将从库节点的内部信息发送给主节点,包括以下四个项目:

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

walreceiver不仅在写入和刷新WAL数据的时候返回ACK响应,还定期发送从库节点心跳(心跳发送间隔通过wal_receiver_status_interval设置,默认10秒)。因此,主库节点始终掌握所有已连接的从库节点状态。

可通过以下查询看到所连接从库相关的LSN信息

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/5000280standby2 | 0/5000280 | 0/5000280 | 0/5000280

3.发生故障时的行为

即使同步从库节点故障,不能再返回ACK响应到主库节点,主库节点也会继续等待从库节点的ACK响应。因此,在主库节点运行的事务会无法提交,后续的查询也无法执行,即主库节点的所有操作都停止(流复制不支持由于超时自动降级为异步模式)。

两种方法避免该情况的发生:

  • 提供多台从库节点来提高系统的可用性;

  • 通过手动执行以下步骤来同步流复制转换到异步流复制。

  • # 1.设置synchronous_standby_names为空串
    synchronous_standby_names = ''#2.执行reload命令重载配置文件
    pg_ctl -D $PGDATA reload
    

管理多个从库节点

1.同步优先级与同步状态

主库节点会为所有的从库节点指定sync_priority(同步优先级)和sync_state(同步状态);

同步优先级

sync_priority表示从库节点在同步模式下的优先级,是一个固定值,其值越小则优先级越高。0是一个特殊值,表示异步模式。从库节点优先级是一个有序列表,按照synchronous_standby_names中的顺序一次给出。

同步状态

sync_stat表示从库节点的状态,其值是由各个从库节点的运行状态以及优先级而定,以下是可能的值:

  • sync:具有最高优先级的同步模式从库节点状态;
  • potential:同步模式下优先级>=2的从库节点状态。如果sync状态(最高优先级)的从库节点故障,优先级第二稿(优先级=2)的从库节点会代替故障节点变为最高优先级;
  • aysnc:异步模式从库节点的固定值,除非修改同步模式,否则他们的状态永远不会是sync和potential;

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

SELECT application_name AS host,sync_priority,sync_state FROM pg_stat_replication;host   | sync_priority | sync_state
----------+---------------+------------standby1 |             1 | syncstandby2 |             2 | potential

2.主库节点管理多个从库节点

主库节点仅等待sync状态从库节点的ACK响应,即主库节点只确保sync主功能太从库节点已写入并刷新WAL数据。因此,在流复制中,只有sync状态的从库节点和主库节点是一直同步的;

下图展示potential状态下从库ACK响应应该早于sync状态从库的情况:此时主库不会完成当前事务的提交,而是要继续等待sync状态从库ACK响应。当收到sync状态从库ACK响应时,主库后端进程才会释放latch并完成事务提交。

  • 如果主库先接受到sync从库的ACK响应,则会立即完成当前事务的提交,而不会去确认potential状态的从库是否已经写入并刷新WAL数据。

3.从库发生故障时的行为

potential或async状态从库节点故障

主库节点会终止连接到故障备份节点walsender进程,并继续进行职级的事务处理。即主库节点的事务处理不厚道这两类从库节点故障的而影响。

sync状态从库节点故障

主库终止连接到故障节点的walsender进程,potential状态从库节点顶替故障的从库节点变为sync状态(期间主库不可用),在替换完成后主库胡肌肤事务处理。因此,从库节点的故障检查对提高流复制高可用至关重要。

从库节点的故障检测

1.从库节点的故障检测

  • 当检测到walsender与walreceiver的连接中断时,主节点立即判定从库节点或walreceiver出现故障;
  • 当底层网络函数由于未能成功读/写walreceiver套接字接口而返回错误时,主库节点会立即判定其失效。

2.硬件或者网络故障检测

如果walreceiver在wal_sender_timeout(默认60s)乜有返回任何节点,则主库节点会认为从库节点出现故障。

根据故障类型,在故障和检测之间可能会有时间差,特别是如果在sync状态从库中发生第二种故障,那么即使有多个potential状态从库节点正常工作,检测到sync状态从库失效,主库仍然会有一段时间不可用。

进程通信详细过程

1.walsender和walreceiver的流复制过程

2.walreceiver和startup进程

PG学习笔记(1)—— 主从复制:流复制相关推荐

  1. Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式

    Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式 主从复制 将主节点的数据改变同步给从节点 作用 备份数据 读写分离 存在的问题: 手动干预切主等操作 主节点的写能力受到单机限制 ...

  2. java学习笔记16--I/O流和文件

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input  Output)流 IO流用来处理 ...

  3. 学习笔记17--场景流之深度估计

    本系列博客包括6个专栏,分别为:<自动驾驶技术概览>.<自动驾驶汽车平台技术基础>.<自动驾驶汽车定位技术>.<自动驾驶汽车环境感知>.<自动驾驶 ...

  4. 嵌入式学习笔记--网络打流补充笔记(iperf3应用)

    前一段时间写了一篇关于打流的简单笔记,包含脚本的简单编写,见 一次打流过程的优化反思(iperf3的灵活运用)_sixtome-CSDN博客_iperf3 打流 这几天在实际应用中,发现还是有不少的瑕 ...

  5. node 流学习笔记 - 可写流

    可写流 可写流没有会创建,有内容的话会清空 默认情况下一次能写 16 * 1024 缓存区,第一次写入是真的向文件里写入,第二次在写入的时候放入到了缓存区里 写入时候返回一个boolean类型,返回为 ...

  6. C++学习笔记(11) 重载流插入运算符和流提取运算符,以及自动类型转换

    1. 重载<< 和>>运算符 <<和<<运算符可以被重载用于输入输出操作,在上一节中,我们对Rational对象进行输出时定义了toString()类成 ...

  7. QtAV学习笔记 解决RTSP流无法播放问题(三)

    前记: 在前面编译成功后,测试QtAV自带的示例,发现本地视频文件.RTMT流可以正常,但无法播放RTSP流,所以单独探究了此问题 一.分析问题 因为之前研究过ffmpeg的使用,所以直接想到,应该是 ...

  8. 电工学习笔记——过孔载流

    作为一个做设计的新手,在刚学pcb设计时,经常会由于电源通道处理不当(过孔数量打的不够.电源通道路径不够宽),而导致PCB设计不合格,生产出来的PCB报废.那么,我们在做PCB设计时电源通道处过孔需要 ...

  9. java学习笔记-初学IO流

    目 录 什么是IO IO流的分类 Java中的IO流 java中需要掌握的流:16个 字节流 java.io.FileInputStream(字节输入流) java.io.FileOutputStre ...

最新文章

  1. linux系统内核文百科,Linux之内核中的文件系统 -电脑资料
  2. BigData之Hadoop:Hadoop的简介、深入理解、下载、案例应用之详细攻略
  3. 简单三步,用 Python 发邮件
  4. 如何使用java程序操作ActiveMQ
  5. 创建用户故事地图的步骤
  6. 清结算内部勾兑业务一个比较有意思的问题整理
  7. Docker中常用的命令
  8. 应对用户需求的四个要点-企业数字化转型外部:驱动力之客户篇...
  9. oracle内存架构(一)
  10. php砸金蛋程序,简单的几句PHP生成美团3周年砸金蛋抽奖代码
  11. 从零开始撸一个Fresco之gif和Webp动画
  12. macOS Big Sur 11.5 (20G71) 虚拟机 ISO 镜像
  13. VS2003安装步骤及其错误
  14. QT移植Linux平台
  15. 如何导出专业的工程图纸(附工图模板)
  16. Keil5 点击Debug Setting 软件崩溃解决方法
  17. 旭日图(Sunburst)
  18. 快速刷新页面ajax出现404,react使用BrowserRouter打包后,刷新页面出现404
  19. 说一说ADI公司的DSP发展历程
  20. how2heap glibc 2.27

热门文章

  1. AutoCad 修改多段线
  2. 18岁、20岁、23岁、25岁、28岁、30岁
  3. 2023第八届少儿模特明星盛典 小超模李迦曈 担任全球赛小主持人
  4. Docker学习笔记八:删除镜像构建私有Registry
  5. Django之restframework中路由Routers
  6. vue tsx render函数 transition动画不生效
  7. 每个人都逃脱不了「认知三原色」
  8. Centos7 编译 php5.6出错
  9. 标准C函数库头文件、POSIX标准库头文件和Windows API函数库头文件说明
  10. python 查找二维数组长度_Python二维数组中的查找