一、搭建一个同步的PostgreSQL集群
上次我们搭建了一个1主1从的异步主从,异步主从,是不能保证主从数据一致的,会有一个延迟状态,这也是为什么叫异步的原因。
我们在上次的基础上搭建了一个一主两从的异步集群,今天,我们来尝试搭建主从同步复制集群。
本次我依然采用的是PG13.8 同一个Linux, 主库端口6100, 从库1端口 6101 ;从库2 端口6102
按照上次的流程我们先搭建一个异步的主从集群,搭建完成如下:
postgres=# select application_name, sync_state from pg_stat_replication;
application_name | sync_state
------------------+------------
ldr | async
rdr | async
(2 rows)
我们上次说过, sync_state 的含义, 上面的async表示是异步的从实例
怎么将异步实例修改成同步实例呢?
1. 修改配置:
synchronous_standby_names = 'ldr, rdr' # standby servers that provide sync rep
# method to choose sync standbys, number of sync standbys,
# and comma-separated list of application_name
# from standby(s); '*' = all
我们尝试修改 synchronous_standby_names 这个参数,这个参数呢让你写同步从库的名字,不仅可以配置同步从库,还能配置从库优先级。
咋? 同步从库还有优先级?啥玩意?
诶不着急,这些东西我们留在下一篇, PG主从复制的原理中来说。
既然修改了重要参数,那我们给主库重启一下~
我们先停掉主库,发现开始不停的报错了,报错内容是连不上主库,看起来有东西一直在根主库连接呀!当然这也不是我们这篇文章的重点,我们先记住这个点,下篇我们来解惑。
[postgres@localhost data]$ pg_ctl stop2023-02-07 14:30:05.606 CST [89828] FATAL: could not connect to the primary server: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 6100?
2. 重启主库
[postgres@localhost data]$ pg_ctl start -D /chason/postgres/instances/pg6100/data/
waiting for server to start....2023-02-07 14:31:50.441 CST [89927] LOG: starting PostgreSQL 13.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16), 64-bit
2023-02-07 14:31:50.443 CST [89927] LOG: listening on IPv4 address "0.0.0.0", port 6100
2023-02-07 14:31:50.443 CST [89927] LOG: listening on IPv6 address "::", port 6100
2023-02-07 14:31:50.447 CST [89927] LOG: listening on Unix socket "/tmp/.s.PGSQL.6100"
2023-02-07 14:31:50.451 CST [89928] LOG: database system was shut down at 2023-02-07 14:30:00 CST
2023-02-07 14:31:50.453 CST [89927] LOG: database system is ready to accept connections
done
server started
[postgres@localhost data]$ 2023-02-07 14:31:50.713 CST [89936] LOG: started streaming WAL from primary at 0/7000000 on timeline 1
2023-02-07 14:31:50.713 CST [89937] LOG: standby "ldr" is now a synchronous standby with priority 1
2023-02-07 14:31:50.713 CST [89937] STATEMENT: START_REPLICATION 0/7000000 TIMELINE 1
2023-02-07 14:31:50.782 CST [89938] LOG: started streaming WAL from primary at 0/7000000 on timeline 1
主库重启成功!
等等,上面的主库重启日志中好像比我以前启动多呀,中间有个什么
standby "ldr" is now a synchronous standby with priority 1
这是个啥意思? 优先级为1? 这个优先级有啥用? 我们买个关子,下集我们说原理的时候一并说。
我们再来看看主从状态:
postgres=# select application_name, sync_priority, sync_state from pg_stat_replication;
application_name | sync_priority | sync_state
------------------+---------------+------------
ldr | 1 | sync
rdr | 2 | potential
(2 rows)
哎? ldr 的状态是 sync 表示是个同步实例了,这咋还有个potential呢?
其实potential呢他其实是个异步实例,官方的解释是
potential 这台后备服务器现在是异步的,但可能在当前的同步后备失效时变成同步的。
哦,明白了说白了这玩意就是个备胎啊, 只有sync是同步的,但是如果sync挂了,备胎就能转正
这个模式呢,其实是PostgreSQL 主从中的常见模式,因为多个同步实例会导致主库的写效率极低,记住,是极低,所以通过这种方式来提高主库写的效率。
为啥强行配置多个同步实例会导致主实例写效率低啊?下集,我们下集讲!
3. 强行配置全同步
那有人就说了,我不管你主库的写效率,我的场景写几乎没有,99%都是查询,我就要配置集群中全同步。
当然也是可以的,我们再次修改配置:
synchronous_standby_names = '2(ldr, rdr)' # standby servers that provide sync rep
# method to choose sync standbys, number of sync standbys,
# and comma-separated list of application_name
# from standby(s); '*' = all
这个配置中2() 表示 () 中包含的实例数,这些实例为一个整体,()里面去写实例名,中间还是用逗号隔开
配置完成之后我们重启主实例:
查看现在的主从状态,发现下面的俩实例都是同步实例了。
postgres=# select application_name, sync_priority, sync_state from pg_stat_replication;
application_name | sync_priority | sync_state
------------------+---------------+------------
rdr | 2 | sync
ldr | 1 | sync
(2 rows)
诶,但是还有个优先级的参数,还是分1和2的优先级,这个有啥用?都是同步了还有优先级?
哈哈哈。老规矩,下集再谈!
二、总结
其实配置主从的同步模式和优先级只要配置一个参数 synchronous_standby_names ;
但是本节,我们埋了一堆坑,我知道你们想唾沫星子喷死我,别急~ 所谓心急吃不了热豆腐,下集的主从原理解析,将会填上本节所有的坑~