基于Docker-compose实现的Postgresql-11的主从复制

参考文章:

http://t.csdn.cn/EnOVn

http://t.csdn.cn/XTJqZ
记录一次主从复制的配置经历

服务器主从角色分配

ipdb 版本角色
192.168.33.23411
192.168.33.22511
docker-compose.yml文件
version: "3.3"
services:
 postgres:
  image: postgresql-gis:11.12-2.5.5
  container_name: postgres-11.12 #容器名
  restart: always
  environment:
      POSTGRES_USER: #用户名
      POSTGRES_PASSWORD: # 密码
  ports:
    - 15332:5432
  volumes:
    - /data/pgdata:/var/lib/postgresql/data	#持久化映射目录

主库配置:

1 创建专用于主从复制的角色

在主库中创建一个专用于复制的角色,角色名onlyrepl ,密码Lin****rd

create role onlyrepl login replication encrypted password 'Lin****rd';

在这里插入图片描述

2 修改pg_hba.conf

在本地本地映射路径/data/pgdata

修改主库/data/pgdata/pg_hba.conf文件:新增onlyrepl相关的配置。

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# 新增:用来做备份的用户,onlyrepl
host    replication     onlyrepl        192.168.33.234/24         md5
host    all             onlyrepl        192.168.33.234/24         trust
  • 注意IP地址(192.168.33.234/24)是本地的是该网段内的IP地址,获取方式:

    ip addr show | grep inet

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kfooevdW-1688020919095)(docker-compose环境下postgresql-11的主从复制.assets/image-20230629090738753.png)]

3 修改 postgresql.conf文件

修改 /data/pgdata/postgresql.conf文件

新增以下配置

wal_level = replica        # minimal, replica, or logical
archive_mode = on        # enables archiving; off, on, or always
archive_command = 'cp %p /var/lib/pgsql/11/data/pg_archive/%f'        # command to use to archive a logfile segment
max_wal_senders = 10       # max number of walsender processes
wal_keep_segments = 10240    # in logfile segments, 16MB each; 0 disables
wal_sender_timeout = 60s    # in milliseconds; 0 disables
log_directory = 'log'    # directory where log files are written

带注释完整版

port = 5432

max_connections = 1000

listen_addresses = '*' #监听本机所有ip,也可以按需设置

shared_buffers = 1280MB            # 数据库的缓存数据大小,建议设置为系统内存的25~50%之间

full_page_writes = on

#日志配置

log_destination = 'csvlog' #日志格式,值为stderr,csvlog,syslog,and eventlog之一

logging_collector = on #开启日志功能,默认是off不启用日志

log_directory = 'log' #日志路径,默认是PGDATA的相对路径,即{PGDATA}/log,可以使用自定义目录

log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' #日志文件命名形式,使用默认即可

log_rotation_age = 1d #单个日志文件的生存期,默认1天,在日志文件大小没有达到log_rotation_size时,一天只生成一个日志文件

log_rotation_size = 1024MB #单个日志文件的大小,如果时间没有超过log_rotation_age,一个日志文件最大只能到1024M,否则将新生成一个日志文件

log_truncate_on_rotation = on #当日志文件已存在时,该配置如果为off,新生成的日志将在文件尾部追加,如果为on,则会覆盖原来的日志

log_lock_waits = off #控制当一个会话等待时间超过deadlock_timeout而被锁时是否产生一个日志信息。在判断一个锁等待是否会影响性能时是有用的,缺省是off

log_statement = 'all' # none, ddl, mod, all 控制记录哪些SQL语句,none不记录;ddl记录所有数据定义命令,比如CREATE,ALTER,和DROP 语句;mod记录所有ddl语句,加上数据修改语句INSERT,UPDATE等;all记录所有执行的语句,将此配置设置为all可跟踪整个数据库执行的SQL语句

log_duration = on #记录每条SQL语句执行完成消耗的时间,将此配置设置为on,用于统计哪些SQL语句耗时较长

log_min_duration_statement = 0 #-1表示不可用,0将记录所有SQL语句和它们的耗时,>0只记录那些耗时超过(或等于)这个值(ms)的SQL语句,log_min_duration_statement会将SQL语句和耗时在同一行记录

log_connections = off #不记录连接日志

log_disconnections = off #不记录连接断开日志

log_line_prefix = '%m [%p] %u %d %r' #日志输出格式,根据需要设置(能够记录时间,用户名称,数据库名称,客户端IP和端口等信息)

log_timezone = 'Asia/Shanghai' #日志时区,和服务器设置同一个时区


#主从复制相关
wal_level = replica	#这个配置用于设置WAL(Write-Ahead Logging)的级别。`replica`级别允许将WAL记录发送到从服务器(standby)以进行流复制(streaming replication)。

archive_mode = on	#这个配置用于启用归档模式,它将WAL记录写入归档目录而不是仅写入WAL日志文件。

archive_command = 'cp %p /var/lib/postgresql/data/pg_archive/%f' #这个配置用于设置归档命令,它定义了如何将WAL记录从WAL日志文件复制到归档目录。在这个例子中,它使用`cp`命令将WAL日志文件复制到指定的归档目录。

wal_keep_segments = 10240 #这个配置用于设置WAL日志文件的最大数量。当达到这个限制时,PostgreSQL将开始删除最旧的WAL日志文件。这个配置可以保留足够长的WAL日志文件以支持从服务器的恢复。

wal_sender_timeout = 60s #这个配置用于设置WAL发送者(WAL sender)的超时时间。如果在指定的时间内没有从主服务器(primary)接收到新的WAL记录,则WAL发送者将关闭连接。

4 重启主库

docker重启,或者docker -compose up 都行

docker restart postgres-11.12

docker logs --tail=200  postgres-11.12

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-irhgU9ug-1688020919096)(docker-compose环境下postgresql-11的主从复制.assets/image-20230629094542259.png)]

  • 重启成功即可

从库配置

1 创建一个新的pg容器

  1. 创建目录:/tools/docker-compose/pg3

  2. 配置docker-compose.yml

    version: "3.3"
    services:
     postgres:
      image: postgresql-gis:11.12-2.5.5
      container_name: pg-achive
      restart: always
      environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: Lin****rd
      ports:
        - 15335:5433
      volumes:
        - /tools/docker-compose/pg3/pgdata:/var/lib/postgresql/data
    
  3. 启动该容器docker-compose up -d

  4. 检查是否成功 docker-compose logs

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ww3FCmnX-1688020919096)(docker-compose环境下postgresql-11的主从复制.assets/image-20230629095442071.png)]

2 复制主库的数据

清空从数据库的data目录rm -rf /var/lib/postgresql/data/

执行指令pg_basebackup -Fp --progress -D /var/lib/postgresql/data/ -R -h 192.168.33.234 -p 15332 -U onlyrepl --password

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSXbdqh3-1688020919097)(docker-compose环境下postgresql-11的主从复制.assets/image-20230629101519714.png)]

  • 成功执行复制

  • 重启容器测试数据已复制过来

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jjAOIwQV-1688020919097)(docker-compose环境下postgresql-11的主从复制.assets/image-20230629102415812.png)]

⭐️遇到无法删除data路径的解决方法

我在操作时遇到无法删除路径的问题,导致报错如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SG2qZhAz-1688020919097)(docker-compose环境下postgresql-11的主从复制.assets/image-20230629101747715.png)]

解决的思路:将主库data文件使用basebackup指令拷贝到docker容器内部的一个临时路径,再使用docker cp指令将data文件拷贝到linux的路径中,重启容器后,新的容器就可以启用新的data文件

# 在docker容器内执行
pg_basebackup -Fp --progress -D /var/lib/postgresql/backup/ -R -h 192.168.33.234 -p 15332 -U onlyrepl --password
# 输入密码

docker cp pg3:/var/lib/postgresql/backup/ /tools/docker-compose/pg3/data
##其中,`/tools/docker-compose/pg3/pgdata`为您要将备份文件存储到本地的路径

3 修改从库配置文件 postgresql.conf

listen_addresses = '*'            # what IP address(es) to listen on;
port = 5432                # (change requires restart)
shared_buffers = 128MB            # min 128kB
dynamic_shared_memory_type = posix    # the default is the first option
wal_level = replica        # minimal, replica, or logical
wal_sender_timeout = 60s    # in milliseconds; 0 disables

max_connections = 1000 #最大连接数

hot_standby = on #说明这台机器不仅仅是用于数据归档,也用于数据查询

max_standby_streaming_delay = 30s #数据流备份的最大延迟时间

wal_receiver_status_interval = 10s #间隔时间

hot_standby_feedback = on #如果有错误的数据复制,是否向主进行反馈

#日志配置

log_destination = 'csvlog' #日志格式,值为stderr,csvlog,syslog,and eventlog之一

logging_collector = on #开启日志功能,默认是off不启用日志

log_directory = 'log' #日志路径,默认是PGDATA的相对路径,即{PGDATA}/log,可以使用自定义目录

log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' #日志文件命名形式,使用默认即可

log_rotation_age = 1d #单个日志文件的生存期,默认1天,在日志文件大小没有达到log_rotation_size时,一天只生成一个日志文件

log_rotation_size = 1024MB #单个日志文件的大小,如果时间没有超过log_rotation_age,一个日志文件最大只能到1024M,否则将新生成一个日志文件

log_truncate_on_rotation = on #当日志文件已存在时,该配置如果为off,新生成的日志将在文件尾部追加,如果为on,则会覆盖原来的日志

log_lock_waits = off #控制当一个会话等待时间超过deadlock_timeout而被锁时是否产生一个日志信息。在判断一个锁等待是否会影响性能时是有用的,缺省是off

log_statement = 'none' # none, ddl, mod, all 控制记录哪些SQL语句,none不记录;ddl记录所有数据定义命令,比如CREATE,ALTER,和DROP 语句;mod记录所有ddl语句,加上数据修改语句INSERT,UPDATE等;all记录所有执行的语句,将此配置设置为all可跟踪整个数据库执行的SQL语句

log_duration = on #记录每条SQL语句执行完成消耗的时间,将此配置设置为on,用于统计哪些SQL语句耗时较长

log_min_duration_statement = 0 #-1表示不可用,0将记录所有SQL语句和它们的耗时,>0只记录那些耗时超过(或等于)这个值(ms)的SQL语句,log_min_duration_statement会将SQL语句和耗时在同一行记录

log_connections = off #不记录连接日志

log_disconnections = off #不记录连接断开日志

log_line_prefix = '%m [%p] %u %d %r' #日志输出格式,根据需要设置(能够记录时间,用户名称,数据库名称,客户端IP和端口等信息)

log_timezone = 'Asia/Shanghai' #日志时区,和服务器设置同一个时区

4 创建恢复文件recovery.conf

# 调整参数:
recovery_target_timeline = 'latest'   #同步到最新数据
standby_mode = on          #指明从库身份
trigger_file = 'failover.now'
primary_conninfo = 'host=192.168.33.234 port=15332 user=onlyrepl password=Lin****rd'   #连接到主库信息

5 测试生效即可

  1. 主库创建一张表
  2. 检查从库是否同步
  3. 同步说明已经创建完成

主从切换(未测试)

文章:http://t.csdn.cn/Cy4Tn

要进行主从切换,需要遵循以下步骤:

1.停止主数据库

docker stop postgres-master

2.在从数据库中创建触发文件

docker exec -it postgres-slave touch /tmp/touch_me_to_promote_to_me_master

3.重新启动从数据库以使更改生效

docker restart postgres-slave

4.确认从数据库已经变成了主数据库

docker exec -it postgres-slave bash
psql -U postgres
SELECT pg_is_in_recovery();
exit

这将返回 false,表示从数据库现在是主数据库,主数据库现在是不可用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Active-Active复制是指两个或多个PostgreSQL数据库实例之间的多向同步。在这种复制方式中,每个数据库实例都可以读取和写入数据,而不是像传统的主从复制方式那样只允许主节点写入数据,从节点只允许读取数据。 下面是使用docker-compose容器实现PostgreSQL Active-Active复制的详细步骤: 1. 创建docker-compose.yml文件并定义两个PostgreSQL容器,如下所示: ``` version: '3' services: postgresql1: image: postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: mydb PGDATA: /var/lib/postgresql/data/pgdata volumes: - pgdata1:/var/lib/postgresql/data ports: - "5431:5432" networks: - postgresql postgresql2: image: postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: mydb PGDATA: /var/lib/postgresql/data/pgdata volumes: - pgdata2:/var/lib/postgresql/data ports: - "5432:5432" networks: - postgresql volumes: pgdata1: pgdata2: networks: postgresql: ``` 2. 启动docker-compose容器,运行以下命令: ``` docker-compose up -d ``` 3. 进入postgresql1容器,创建复制用户并授权: ``` docker exec -it postgresql1 bash su postgres psql CREATE USER replication WITH REPLICATION ENCRYPTED PASSWORD 'password'; GRANT ALL PRIVILEGES ON DATABASE mydb TO replication; ``` 4. 修改postgresql.conf文件和pg_hba.conf文件 在postgresql1容器的 /var/lib/postgresql/data 目录下找到postgresql.conf文件和pg_hba.conf文件,修改如下: postgresql.conf: ``` listen_addresses = '*' wal_level = replica max_wal_senders = 10 wal_keep_segments = 32 ``` pg_hba.conf: ``` host replication replication 172.20.0.0/16 md5 ``` 5. 重启postgresql1容器 ``` docker-compose restart postgresql1 ``` 6. 在postgresql2容器中创建复制槽并启动复制流 ``` docker exec -it postgresql2 bash su postgres psql SELECT * FROM pg_create_physical_replication_slot('replication_slot_name'); pg_basebackup -h postgresql1 -D /var/lib/postgresql/data -U replication -v -P --xlog-method=stream pg_ctl -D /var/lib/postgresql/data start ``` 7. 测试Active-Active复制 在任何一个容器中创建表或插入数据,可以在另一个容器中看到相同的数据。如果其中一个容器出现故障,另一个容器可以继续提供服务,因为它们都具有相同的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xcong_Zhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值