一、前言
主从的流复制,可以根据
synchronous_commit
synchronous_standby_names
这俩参数来设置强同步。
首先搭建了3台虚拟机,1主、2从
搭库安装这写我就懒得写了。
二、主库配置
1、用户
需要设置一个用户用来流复制
create user replica with password 'replica';(用superuser也可以)
alter user replica replication;
2、pg_hba.conf
host replication all 192.168.79.111/24 trust
host replication all 192.168.79.112/24 trust
3、postgresql.conf
listen_addresses = '*'
wal_level = replica
port = 5434
archive_mode=on
archive_command='cp %p //usr/local/postgresql/archive/%f'
archive_timeout=1800
max_wal_senders = 10
wal_sender_timeout = 60s
max_replication_slots = 10
logging_collector = on
log_directory = '/usr/local/postgresql/log'
synchronous_commit=on
synchronous_standby_names = 'FIRST 1(S1,S2)' --这一行先写好,但是需要注释掉。
这样主库的配置就完成了,需要去从库pg_basebackup来备份过去
三、从库配置
3.1、从库配置
pg_basebackup -D /usr/local/postgresql/data -h 192.168.79.110 -p 5432 -U replica -X stream -Pv -R
从库先备份,备份完了之后需要去修改
pg_recovery.conf
在primary_conninfo参数里面加:
application_name=S1
S1就是我设置的强同步node
S2就是预备库
然后启动即可。
3.2、查看:
主:
select * from pg_stat_replication ;
可见图内sync就是强同步节点。
从:
select * from pg_stat_wal_receiver;
3.3、测试
zcjcs表试试
主:
S1:
S2:
四、强同步参数理解
4.1、参数synchronous_standby_names:
(同步备库的名字)
控制事务提交时是否需要等待wal recard 被复制到standby servers。
默认为空,如果为空的话,则下面前4项都为'无备库等wal刷盘'状态)
语法:
~~[FIRST] num_sync (standby_name[,....]
~~ANY num_sync (standby_name[,....])
~~standby_name[,...] 这种等于FIRST1
如:FIRST 3(s1,s2,s3,s4) 这样就会优先从前往后算3个,同步数据库(强一致sync状态)
S4就是潜在备库(potential状态),当sync的备库断掉的话,会自动补上。
(平时是async异步状态)
sync_state里有分别
(select usename,application_name,client_addr,sync_state from pg_stat_replication;)
ANY 任意几个
4.2、参数synchronous_commit
向客户端返回success信息的参数
on (默认):两种情况:
无备库,则等主库wal刷到磁盘后,主库才可以向客户端提交
有备库,则需要备库从os cache缓存,刷到磁盘,主库才可以向客户端提交
有两份持久化wal日志
local :保证本机wal日志刷新到磁盘,主库才可以向客户端提交
不管备库状态,
至少可以保证有一份wal持久化日志
remote_write :等主库wal刷到磁盘后,
同时日志传递到备库的os cache缓存中,
(但是还未刷盘),主库才可以向客户端提交
不能避免操作系统崩溃,因为在os cache中,没有真正进入磁盘
remote_apply :完全同步,
等主库wal刷到磁盘后,
备库启动startup一个进程,在内存里重放,
并且到os cache缓存,且刷盘,主库才可以向客户端提交
有两份持久化wal日志
也就是说remote_apply的情况下,
主库做了insert,客户端收到信息后,并且可以在从库查询到,因为已经回放
(前4种都是缺保本地WAL刷盘)
off :异步模式
数据只写到wal buffer里面,不写到磁盘,主库就向客户端提交
数据库忽然崩溃的话,会丢失数据,因为没写到磁盘里。
但是能保证数据一致
五、强同步从库挂掉时状态
从库如果挂了主库就没法增删改
此时看锁状态
select pid,query,wait_event,wait_event_type from pg_stat_activity;
(wait_event :Syncrep 等待返回 )
( walsendermain 流复制发送)
5.1、测试1、:
我先把node S1 模拟宕机。
可见此时备库从potential 潜在备库变为sync强同步状态。
这是因为我配置的是 FIRST 1 (S1,S2)
当S1挂掉,备用库就会去充当S1的角色。
5.2、测试2、:
我将主库的 FIRST 1 (S1,S2)
改为 FIRST 2(S1,S2)
查看参数为pg_ctl reload就可以生效
此时两个节点都为sync强同步状态
于是我模拟挂掉一个节点
再次执行插入就一直在等待
此时我再打开一个窗口 去主库查看锁状态。
可见此时状态为:wait_event :Syncrep 等待返回
等我再次开启从库时,立刻插入完毕。
本次实验完成。