Pgsql-Cluster
前面介绍了 PostgreSQL 常用函数、锁操作、执行计划、视图与触发器、存储过程、索引、分区分表、事务与并发控制相关的知识点,今天我将详细的为大家介绍 PostgreSQL 主从同步复制原理与实践相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!!
在正式介绍 PostgreSQL 主从同步复制 之前,我们先了解一下 PostgreSQL 的预写日志机制(WAL)。
PostgreSQL 预写日志机制(WAL)
1. 关于持久性
持久性是指,事务提交后,对系统的影响必须是永久的,即使系统意外宕机,也必须确保事务提交时的修改已真正永久写入到永久存储中。
最简单的实现方法,当然是在事务提交后立即刷新事务修改后的数据到磁盘。但是磁盘和内存之间的IO操作是最影响数据库系统影响时间的,一有事务提交就去刷新磁盘,会对数据库性能产生不好影响。
WAL机制的引入,即保证了事务持久性和数据完整性,又尽量地避免了频繁IO对性能的影响。
2. WAL过程分析
Write-Ahead Logging,前写日志。
在MVCC的部分中,我们已经分析了PostgreSQL的存储结构:元组-文件页-物理段-表; 以及写数据的步骤:先写到缓冲区Buffer-再刷新到磁盘Disk。
WAL机制实际是在这个写数据的过程中加入了对应的写wal log的过程,步骤一样是先到Buffer,再刷新到Disk。
-
Change发生时:
- 先将变更后内容记入WAL Buffer
- 再将更新后的数据写入Data Buffer
-
Commit发生时:
- WAL Buffer刷新到Disk
- Data Buffer写磁盘推迟
-
Checkpoint发生时:
- 将所有Data Buffer刷新到磁盘

- 数据发生变动时

更多关于 PostgreSQL 系列的学习文章,请参阅:PostgreSQL 数据库,本系列持续更新中。
WAL的好处
通过上面的分析,可以看到:
当宕机发生时,
- Data Buffer的内容还没有全部写入到永久存储中,数据丢失;
- 但是WAL Buffer的内容已写入磁盘,根据WAL日志的内容,可以恢复库丢失的内容。
在提交时,仅把WAL刷新到了磁盘,而不是Data刷新:
- 从IO次数来说,WAL刷新是少量IO,Data刷新是大量IO,WAL刷新次数少得多;
- 从IO花销来说,WAL刷新是连续IO,Data刷新是随机IO,WAL刷新花销小得多。
因 此WAL机制在保证事务持久性和数据完整性的同时,成功地提升了系统性能。
主从复制
1. 基于文件的日志传送
创建一个高可用性(HA)集群配置可采用连续归档,集群中主服务器工作在连续归档模式下,备服务器工作在连续恢复模式下(1台或多台可随时接管主服务器),备持续从主服务器读取WAL文件。
连续归档不需要对数据库表做任何改动,可有效降低管理开销,对主服务器的性能影响也相对较低。
直接从一个数据库服务器移动 WAL 记录到另一台服务器被称为日志传送,PostgreSQL 通过一次一文件(WAL段)的WAL记录传输实现了基于文件的日志传送。
- 日志传送所需的带宽取根据主服务器的事务率而变化;
- 日志传送是异步的,即WAL记录是在事务提交后才被传送,那么在一个窗口期内如果主服务器发生灾难性的失效则会导致数据丢失,还没有被传送的事务将会被丢失;
- 数据丢失窗口可以通过使用参数archive_timeout进行限制,可以低至数秒,但同时会增加文件传送所需的带宽。
2. 流复制
PostgreSQL 在9.x之后引入了主从 的流复制机制,所谓流复制,就是备服务器通过tcp流从主服务器中同步相应的数据,主服务器在WAL记录产生时即将它们以流式传送给备服务器,而不必等到WAL文件被填充。
- 默认情况下流复制是异步的,这种情况下主服务器上提交一个事务与该变化在备服务器上变得可见之间客观上存在短暂的延迟,但这种延迟相比基于文件的日志传送方式依然要小得多,在备服务器的能力满足负载的前提下延迟通常低于一秒;
- 在流复制中,备服务器比使用基于文件的日志传送具有更小的数据丢失窗口,不需要采用archive_timeout来缩减数据丢失窗口;
- 将一个备服务器从基于文件日志传送转变成基于流复制的步骤是:把recovery.conf文件中的primary_conninfo设置指向主服务器;设置主服务器配置文件的listen_addresses参数与认证文件即可。
- 更多关于 PostgreSQL 系列的学习文章,请参阅:PostgreSQL 数据库,本系列持续更新中。
PostgreSql 主从同步搭建
1. 环境
- 操作系统: CentOS Linux release 7.6.1810 (Core)
- 数据库版本: PostgreSQL 12.4
- 主库IP 192.168.100.170
- 从库IP 192.168.100.202
2. 主库配置
主库创建账号同步数据
psql -h localhost -p 5432 -U postgres -W -d postgres
CREATE ROLE replica login replication encrypted password 'replica';
DROP ROLE "replica";
DROP USER "light";
主库 pg_hba.conf 文件增加备库访问控制
host replication replica 192.168.100.202/32 trust

主库 postgresql.conf 文件添加主从同步参数
wal_level = hot_standby
max_wal_senders = 8
wal_keep_segments = 64
wal_sender_timeout = 60s
max_connections = 100
