Docker 中 PostgreSql 主从热备,主从切换方案
环境说明
- Docker
- Windows 11
- PostgreSql 17
搭建步骤
0. 宿主机准备:
- 找个地方创建一个文件夹用来挂载容器中数据库Data文件夹,这里我用的是:
C:\Users\Administrator\docker\Postgresql\replication
1. 主数据库准备:
- 执行docker run 命令,创建主数据库容器:pgsmaster
docker run --name pgsmaster -p 5400:5432 -e POSTGRES_PASSWORD=123456 -v C:\Users\Administrator\docker\Postgresql\replication\pgsmaster:/var/lib/postgresql/data -d postgres
- 添加复制角色用户:
# 1.进入容器
docker exec -it pgsmaster bash
# 2.连接PostgreSQL
psql -U postgres
# 3.创建用户
// replicator: 复制账号; 123456: 认证密码
create role replicator login replication encrypted password '123456';
# 4.验证用户
\du
# 出现如下列表则用户创建成功
List of roles
Role name | Attributes
-----------+-------------------------------------------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS
replicator | Replication
-
宿主机找到挂载文件夹:
C:\Users\Administrator\docker\Postgresql\replication\pgsmaster
下的postgresql.conf
文件,修改配置:1. listen_addresses ='*' 2. wal_level = replica
-
找到
pg_hba.conf
文件,最后一行添加配置:
host replication replicator 172.17.0.0/16 md5
- 重启容器:
docker restart pgsmaster
到这里主数据库就准备好了~
2. 从数据库准备:
- 同样执行docker run 命令,创建一个从数据库容器:
docker run --name pgsslave -p 5401:5432 -e POSTGRES_PASSWORD=123456 -v C:\Users\Administrator\docker\Postgresql\replication\pgsslave:/var/lib/postgresql/data -d postgres
- 进入容器,进行主库复制:
# 1. 进入容器
docker exec -it pgsslave bash
# 2. 切换postgres用户
su postgres
# 3. 清空data文件夹
rm -rf /var/lib/postgresql/data/*
# 4. 执行复制, 需要输入密码即主数据库创建复制用户replicator的密码‘123456’
pg_basebackup -h 172.17.0.6 -U replicator -R -P -v -C --slot=pgsslave -D /var/lib/postgresql/data
[!NOTE] 命令说明:
-R 说明会创建standby.signal文件,以及补充postgresql.auto.conf的内容
-P 显示备份进度
-v 显示更加详细信息
-C 同时创建复制槽
-slot 指定复制槽的名字(一个备库一个名字)
-D 生成备库的路径
[!NOTE] 复制槽的好处:
主库的事务日志一直处于滚动消耗的状态,如果备库下线,随着主库频繁的数据变动,可能就会存在当备库重新上线后,已经找不到之前没有拉取的事务日志的情况(被主库回收掉了)。
但是有了复制槽,主库就会为复制槽保留它没有消费的日志,等待它上线后进行消费。当然代价是对磁盘的消耗,不过只要备库不是永久丢失,磁盘消耗对于大部分场景来说不是问题。
但是如果备库永久丢失了,要记得删除主库中对应的复制槽。删除复制槽的语句为 :select pg_drop_replication_slot('pgsslave');
- 重启容器
docker restart pgsslave
- 确认是否成功, 主库执行下列查询即可
select * from pg_replication_slots;\\查询主库中的插槽
select * from pg_stat_replication;\\查询已建立连接的备份库
主从切换
1. 从库切换成主库
使用以下语句将从库切换成主库
select pg_promote();
此时,从库data中的standby.signal文件已删除;并修改pg_hba.conf 文件,ip改为原主库ip
host replication replicator 172.17.0.0/16 md5
2. 删除原主库复制槽
select pg_drop_replication_slot('pgsslave2');
3. 将原从库的data备份到原主库
这一步是全量备份,所以要注意如果库很大,会很费时间,虽然官方文档说不会影响其他客户端,但是肯定会消耗主库的cpu,内存,磁盘I/O以及带宽;
pg_basebackup -h 172.17.0.7 -U replicator -R -P -v -C --slot=pgsslave -D /var/lib/postgresql/data
此时,主库就会变成从库,从库中也能查询到对应的备份连接
测试
1. 监控延迟
PostgreSQL 提供了一些系统视图和函数来检查复制延迟:
pg_stat_replication
:该视图显示主数据库的流复制状态,包括从数据库的复制延迟。可以使用以下查询来查看当前的延迟:
SELECT
application_name,
client_addr,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replication_lag
FROM pg_stat_replication;
-- 其中,replication_lag 表示主数据库当前生成的 WAL 日志比从数据库已应用的日志多出多少个字节。则表示是延迟大小。
2. 主库宕机
- 从库停止接受WAL日志,等待主库恢复。
- 从库查询服务不受影响,可以继续接受只读查询。
- 主库手动恢复后,从库会开始从主库接收 WAL 日志并恢复同步,恢复过程是自动的。
3. 从库宕机
- 从库停止接受WAL日志且无法提供查询服务。
- 主库读写正常,不受影响。
- 从库手动恢复后,从库自动消费积压的WAL日志并与主库同步。
posted on 2024-11-28 15:48 God写注释没有代码 阅读(244) 评论(1) 编辑 收藏 举报