参考文章:
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';
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
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
- 重启成功即可
从库配置
1 创建一个新的pg容器
-
创建目录:
/tools/docker-compose/pg3
-
配置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
-
启动该容器
docker-compose up -d
-
检查是否成功
docker-compose logs
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
-
成功执行复制
-
重启容器测试数据已复制过来
⭐️遇到无法删除data路径的解决方法
我在操作时遇到无法删除路径的问题,导致报错如下:
解决的思路:将主库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 测试生效即可
- 主库创建一张表
- 检查从库是否同步
- 同步说明已经创建完成
主从切换(未测试)
文章: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,表示从数据库现在是主数据库,主数据库现在是不可用的。