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

参考文章:

http://t.csdn.cn/EnOVn

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

服务器主从角色分配

ip db 版本 角色
192.168.33.234 11
192.168.33.225 11

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';

基于Docker-compose实现的Postgresql-11的主从复制_第1张图片

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

    基于Docker-compose实现的Postgresql-11的主从复制_第2张图片

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

基于Docker-compose实现的Postgresql-11的主从复制_第3张图片

  • 重启成功即可

从库配置

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

    基于Docker-compose实现的Postgresql-11的主从复制_第4张图片

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)]

  • 成功执行复制

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

    基于Docker-compose实现的Postgresql-11的主从复制_第5张图片

⭐️遇到无法删除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,表示从数据库现在是主数据库,主数据库现在是不可用的。

你可能感兴趣的:(问题总结,学习笔记,docker,postgresql,容器)