都说数据无价,本文就介绍一下如何快速拥有一个PostgreSQL
的备库,从而实现主从数据库。通常情况下,从库可以作为一个备份的存在(只读),当主库出现宕机后,我们可以快速把从库提升为主库(读写)。步骤并不复杂,一起来尝试一下吧。
创建用户,专门用来实现数据复制
create user replica with replication login password 'replication';
检查postgresql.conf
配置文件
wal_level = replica
检查pg_hba.conf
权限配置文件
建议在最后追加一行host replication replica all md5
,其中all
也可以替换为从库所处机器的ip
地址,比如192.168.0.10/32
生成备份库
pg_basebackup -h 192.168.0.21 -p 54321 -U replica -R -P -v -C --slot=pgstandby1 -D /Users/liurui/pg2
- -R 说明会创建
standby.signal
文件,以及补充postgresql.auto.conf
的内容 - -P 显示备份进度
- -v 显示更加详细信息
- -C 同时创建复制槽
- --slot 指定复制槽的名字(一个备库一个名字)
- -D 生成备库的路径
复制槽的好处
主库的事务日志一直处于滚动消耗的状态,如果备库下线,随着主库频繁的数据变动,可能就会存在当备库重新上线后,已经找不到之前没有拉取的事务日志的情况(被主库回收掉了)。
但是有了复制槽,主库就会为复制槽保留它没有消费的日志,等待它上线后进行消费。当然代价是对磁盘的消耗,不过只要备库不是永久丢失,磁盘消耗对于大部分场景来说不是问题。
但是如果备库永久丢失了,要记得删除主库中对应的复制槽。删除复制槽的语句为select pg_drop_replication_slot('pgstandby1');
注意
备库的操作系统环境最好与主库一致,如果一个是Windows一个是Linux,几乎一定会遇到字符集不一致的问题,导致备库无法启动。
启动备库
pg_ctl -D /Users/liurui/pg2 start
验证流复制可用性
- 在主库进行数据变动,在备库可进行观察
- 在主库执行
select * from pg_replication_slots;
能够观察到复制槽 - 在主库执行
select * from pg_stat_replication;
可以观察到备库连接情况,只有备库上线的情况下,该查询才会返回数据 - 顺便说一下,从库的数据目录会生成名为
postgresql.auto.conf
的文件(对应上面的-R
参数),里面存放了主库的连接信息,感兴趣的小伙伴可以观察看看,但是这个文件不建议手动编辑。 - 注意,这样创建的备库其实叫异步备库,极端情况下,备库的数据跟主库比是有一定延迟的,如果需要无延迟的备库,就需要启动
同步
模式,当然它会牺牲更多的性能,也要付出更高的运维成本,本文并不涉及同步
模式的介绍。
如何获得指定延迟时间的备库(可选)
大部分情况下,备库与主库保持一致是我们需要的。但是有时候,我们也需要的也一个比主库有延迟的备库,比如延迟三十分钟
,也就意味着,当主库的数据被不小心删除后,三十分钟内,我们都可以在备库里找到。此时需要在备库配置:
recovery_min_apply_delay = 30min
手动把备库提升为主库
备库平时只能作为只读数据库使用,因为可写数据是主库才有的特权。但是一旦主库挂掉,并且已知备库的数据足够完整的情况下,我们可以迅速把备库提升为主库。只要找到备库的文件路径,把里面的standby.signal
文件删除即可。顺便说一下,这个文件是没有内容的,它是一个空文件,通过这个文件的存在来表明自己是个备库,所以删掉或者重命名该文件,都能把这个备库提升为主库。当然,别忘了删除该文件后,重启备库才能生效。
补充:在docker环境下生成备库
-
像平常在
docker
使用一样,启动一个数据库,当然要注意该备库的版本与主库保持一致。一个典型的yml文件如下:version: '3' services: postgres15-bak: image: postgres:15.1 ports: - 34325:5432 volumes: - /root/docker/volume/postgres15:/var/lib/postgresql/data
-
使用
docker-compose
启动该镜像后,再通过docker exec
进入它 -
切换用户:
su postgres
-
进入
postgres
拥有权限的路径:cd /var/lib/postgresql/data
-
生成备库:
pg_basebackup -h 192.168.0.21 -p 54321 -U replica -R -P -v -C --slot=pgstandby1 -D ./bak
此时备库路径就在/var/lib/postgresql/data/bak
下 -
退出
docker
,回到宿主机,并关闭刚刚使用的docker
镜像 -
在宿主机把刚才镜像映射的文件夹调整一下,以上面的
yml
文件为例,就应该先把/root/docker/volume/postgres15/bak
文件夹拷贝出来,再把/root/docker/volume/postgres15
文件夹删除掉,之后把刚拷贝出来的bak
文件夹还原为/root/docker/volume/postgres15
,此时该镜像映射的文件夹就是我们新产生的从库备份了。 -
启动上面的
docker
镜像。则从库已经接入主库。