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 replicator172.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 replicator172.17.0.0/16 md52. 删除原主库复制槽
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日志并与主库同步。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]