PG学习笔记(1)—— 主从复制:流复制
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.启动过程
- 启动主从服务器;
- 从库节点启动startup进程;
- 从库节点启动walreceiver进程;
- walreceiver进程向主库节点发送连接请求,如果主库尚未启动,walreceiver会定期重发该请求;
- 当主节点收到连接请求时,将启动walsender进程,并建立walsender和walreceiver之间的TCP连接;
- walreceiver发送从库节点最新的LSN;
- 如果从库最新的LSN小于主库最新LSN,即落后。walsender会将前一个LSN到后一个LSN之间的wal数据发送到walreceiver;
- 流复制开始工作。
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语句、然后立即提交事务。分析如下:
- 后台进程执行XLogInsert()和XLogFlush()函数,将wal数据写入缓存并flush到wal段文件;
- walsender将写入的wal段文件的wal数据发送到walreceiver;
- 主库节点发送wal数据后,后端进程继续等待来自从库节点的ACK响应。即后台进程执行内部函数SyncRepWaitForLSN()来获取latch,并等待释放;
- walreceiver通过write()函数将接收到的wal数据写入从库节点的wal缓存,并且返回ACK响应给walsender;
- walreceiver通过fsync()函数将wal数据全部flush到wal段文件,并且再返回一个ACK响应给walsender,通知startup进程wal相关数据已更新;
- startup进程应用写入wal段文件的wal数据;
- 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)—— 主从复制:流复制相关推荐
- Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式
Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式 主从复制 将主节点的数据改变同步给从节点 作用 备份数据 读写分离 存在的问题: 手动干预切主等操作 主节点的写能力受到单机限制 ...
- java学习笔记16--I/O流和文件
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input Output)流 IO流用来处理 ...
- 学习笔记17--场景流之深度估计
本系列博客包括6个专栏,分别为:<自动驾驶技术概览>.<自动驾驶汽车平台技术基础>.<自动驾驶汽车定位技术>.<自动驾驶汽车环境感知>.<自动驾驶 ...
- 嵌入式学习笔记--网络打流补充笔记(iperf3应用)
前一段时间写了一篇关于打流的简单笔记,包含脚本的简单编写,见 一次打流过程的优化反思(iperf3的灵活运用)_sixtome-CSDN博客_iperf3 打流 这几天在实际应用中,发现还是有不少的瑕 ...
- node 流学习笔记 - 可写流
可写流 可写流没有会创建,有内容的话会清空 默认情况下一次能写 16 * 1024 缓存区,第一次写入是真的向文件里写入,第二次在写入的时候放入到了缓存区里 写入时候返回一个boolean类型,返回为 ...
- C++学习笔记(11) 重载流插入运算符和流提取运算符,以及自动类型转换
1. 重载<< 和>>运算符 <<和<<运算符可以被重载用于输入输出操作,在上一节中,我们对Rational对象进行输出时定义了toString()类成 ...
- QtAV学习笔记 解决RTSP流无法播放问题(三)
前记: 在前面编译成功后,测试QtAV自带的示例,发现本地视频文件.RTMT流可以正常,但无法播放RTSP流,所以单独探究了此问题 一.分析问题 因为之前研究过ffmpeg的使用,所以直接想到,应该是 ...
- 电工学习笔记——过孔载流
作为一个做设计的新手,在刚学pcb设计时,经常会由于电源通道处理不当(过孔数量打的不够.电源通道路径不够宽),而导致PCB设计不合格,生产出来的PCB报废.那么,我们在做PCB设计时电源通道处过孔需要 ...
- java学习笔记-初学IO流
目 录 什么是IO IO流的分类 Java中的IO流 java中需要掌握的流:16个 字节流 java.io.FileInputStream(字节输入流) java.io.FileOutputStre ...
最新文章
- linux系统内核文百科,Linux之内核中的文件系统 -电脑资料
- BigData之Hadoop:Hadoop的简介、深入理解、下载、案例应用之详细攻略
- 简单三步,用 Python 发邮件
- 如何使用java程序操作ActiveMQ
- 创建用户故事地图的步骤
- 清结算内部勾兑业务一个比较有意思的问题整理
- Docker中常用的命令
- 应对用户需求的四个要点-企业数字化转型外部:驱动力之客户篇...
- oracle内存架构(一)
- php砸金蛋程序,简单的几句PHP生成美团3周年砸金蛋抽奖代码
- 从零开始撸一个Fresco之gif和Webp动画
- macOS Big Sur 11.5 (20G71) 虚拟机 ISO 镜像
- VS2003安装步骤及其错误
- QT移植Linux平台
- 如何导出专业的工程图纸(附工图模板)
- Keil5 点击Debug Setting 软件崩溃解决方法
- 旭日图(Sunburst)
- 快速刷新页面ajax出现404,react使用BrowserRouter打包后,刷新页面出现404
- 说一说ADI公司的DSP发展历程
- how2heap glibc 2.27