max复制关键帧到不同的文件_PostgreSQL12主从流复制

流复制原理

PostgrepSQL在数据目录的子目录pg_xlog子目录中维护了一个WAL日志文件,可以把WAL日志备份到另外一台备份服务器,通过重做WAL日志的方式在备服务器上恢复数据(类似Oracle的redo日志)。

WAL日志复制到另外一台备份服务器可以有两种方式:

1、 WAL日志文件复制

此种方式是写完一个WAL日志后,才把WAL日志文件拷贝到备份数据库中。这样通常备份会落后主库一个WAL日志文件,当主数据库发生故障时,主数据库的WAL文件并没有填充完毕未传输(默认16MB)、或者时延等原因导致WAL文件没有传输完毕,会导致被数据库可能存在一定的数据丢失。此种方式是postgreSQL9.0前版本主要提供的WAL日志复制机制。

采用此方式的WAL复制,需要:

  • 主数据库的wal_level配置为archive或以上。
  • PostgreSQL 9.1之后提供了一个很方便的工具pg_basebackup,使用完成一次基础备份到备数据库。
  • 后续产生WAL文件,可以通过archive_command参数调度命令传输至备机。

2、流复制(Streaming Replication)

流复制是PostgreSQL 9.0之后才提供的新的传递WAL日志的方法。通过流复制,备库不断的从主库同步相应的数据,并在备库apply每个WAL record,这里的流复制每次传输单位是WAL日志的record。它的好处是只要主库一产生日志,就会马上传递到备库,同WAL日志文件相比有更低同步延迟。

同时PostgreSQL9.0之后提供了Hot Standby能力,备库在应用WAL record的同时也能够提供只读服务。

PostgreSQL的流复制最多支持1主8备、支持级联复制(主->备1,备1->备2)。

PostgreSQL流复制的核心部分由walsender,walreceiver和startup三个进程组成:

  1. walreceiver启动后通过recovery.conf文件中的primary_conninfo参数信息连向主库,主库通过连接参数replication=true启动walsender进程。
  2. walreceiver执行identify_system命令,获取主库systemid/timeline/xlogpos等信息,执行TIMELINE_HISTORY命令拉取history文件。
  3. 执行wal_startstreaming开始启动流复制,通过walrcv_receive获取WAL日志,期间也会回应主库发过来的心跳信息(接收位点、flush位点、apply位点),向主库发送feedback信息(最老的事务id),避免vacuum删掉备库正在使用的记录。
  4. 执行walrcv_endstreaming结束流复制,等待startup进程更新receiveStart和receiveStartTLI,一旦更新,重新进入2/3/4步骤。

fd5a92ad7e36dd7a049a050409bb04bb.png

WAL流复制支持同步、异步方式:

  • 异步流复制模式中,主库提交的事务不会等待备库接收WAL日志流并返回确认信息,因此异步流复制模式下主库与备库的数据版本上会存在一定的处理延迟,延迟的时间主要受主库压力、备库主机性能、网络带宽等影响,当正常情况下,主备的延迟通常在毫秒级的范围内,当主库宕机,这个延迟就主要受到故障发现与切换时间的影响而拉长,不过虽然如此,这些数据延迟的问题,可以从架构或相关自动化运维手段不断优化设置。
  • 同步流复制模式中,要求主库把WAL日志写入磁盘,同时等待WAL日志记录复制到备库、并且WAL日志记录在任何一个备库写入磁盘后,才能向应用返回Commit结果。一旦所有备库故障,在主库的应用操作则会被挂起,所以此方式建议起码是1主2备。

二、搭建PostgreSQL数据库异步流复制环境

主机:10.255.0.62

从机:10.255.0.64

前面安装按照安装手册实行,并启动主数据服务,从数据库安装好不启动;

在主机上执行;

/usr/local/pgsql/data

修改postgresql.conf

wal_level = replica  # 这个是设置主为wal的主机
max_wal_senders = 5 # 这个设置了可以最多有几个流复制连接,差不多有几个从,就设置几个
wal_keep_segments = 128 # 设置流复制保留的最多的xlog数目
wal_sender_timeout = 60s # 设置流复制主机发送数据的超时时间
max_connections = 200 # 一般查多于写的应用从库的最大连接数要比较大
hot_standby = on # 说明这台机器不仅仅是用于数据归档,也用于数据查询
max_standby_streaming_delay = 30s # 数据流备份的最大延迟时间
wal_receiver_status_interval = 10s # 多久向主报告一次从的状态,当然从每次数据复制都会向主报告状态,这里只是设置最长的间隔时间
hot_standby_feedback = on # 如果有错误的数据复制,是否向主进行反馈
wal_log_hints = on # also do full page writes of non-critical updates

/var/lib/pgsql/12/data/

修改pg_hba.conf

local all all trust
host all all 0.0.0.0/0 md5
host all all ::1/128 trust
host replication replica 0.0.0.0/0 md5

添加流复制用户

create role replica with replication login password ‘123456’;
alter user replica with password ‘123456’;

从机执行;

清空数据文件夹

rm -rf /usr/local/pgsql/data/*
cd /usr/local/pgsql/data

pg_basebackup -h 10.255.0.62 -p 5432 -U replica  -Fp -Xs -Pv -R -D /usr/local/pgsql/data
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/2000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_227055"
24591/24591 kB (100%), 1/1 tablespace                                         
pg_basebackup: write-ahead log end point: 0/2000100
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed

设置data权限

chmod 750 /usr/local/pgsql/data

编辑standby.signal文件

# 添加

standby_mode = 'on'

vi /usr/local/pgsql/data/postgresql.conf

primary_conninfo = 'host=10.255.0.62 port=5432 user=replica password=123456'
recovery_target_timeline = latest # 默认
max_connections = 120 # 大于等于主节点,正式环境应当重新考虑此值的大小
hot_standby = on
max_standby_streaming_delay = 30s
wal_receiver_status_interval = 10s
hot_standby_feedback = on
max_wal_senders = 15

启动

pg_ctl -D /usr/local/pgsql/data start

5.查看状态

主库

ps -ef | grep postgres
postgres  50756      1  0 Sep01 ?        00:00:00 /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
postgres  50759  50756  0 Sep01 ?        00:00:00 postgres: checkpointer   
postgres  50760  50756  0 Sep01 ?        00:00:00 postgres: background writer   
postgres  50761  50756  0 Sep01 ?        00:00:00 postgres: walwriter   
postgres  50762  50756  0 Sep01 ?        00:00:00 postgres: autovacuum launcher   
postgres  50763  50756  0 Sep01 ?        00:00:00 postgres: stats collector   
postgres  50764  50756  0 Sep01 ?        00:00:00 postgres: logical replication launcher   
root     221972 220679  0 15:02 pts/0    00:00:00 su - postgres
postgres 221973 221972  0 15:02 pts/0    00:00:00 -bash
postgres 227742  50756  0 15:57 ?        00:00:00 postgres: walsender replica 10.255.0.64(36366) streaming 0/3000148
postgres 227851 221973  0 15:58 pts/0    00:00:00 ps -ef
postgres 227852 221973  0 15:58 pts/0    00:00:00 grep --color=auto postgres

从库

ps -ef | grep postgres
root     211506 211272  0 14:52 pts/0    00:00:00 su - postgres
postgres 211507 211506  0 14:52 pts/0    00:00:00 -bash
postgres 218382      1  0 15:57 ?        00:00:00 /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
postgres 218383 218382  0 15:57 ?        00:00:00 postgres: startup   recovering 000000010000000000000003
postgres 218384 218382  0 15:57 ?        00:00:00 postgres: checkpointer   
postgres 218385 218382  0 15:57 ?        00:00:00 postgres: background writer   
postgres 218386 218382  0 15:57 ?        00:00:00 postgres: stats collector   
postgres 218387 218382  0 15:57 ?        00:00:00 postgres: walreceiver   streaming 0/3000148
postgres 218546 211507  0 15:59 pts/0    00:00:00 ps -ef
postgres 218547 211507  0 15:59 pts/0    00:00:00 grep --color=auto postgres

查看主/从库状态S

/usr/pgsql-12/bin/pg_controldata -D /var/lib/pgsql/12/data
/usr/pgsql-12/bin/pg_controldata -D /var/lib/pgsql/12/data | grep 'Database cluster state' 
#主库显示:Database cluster state: in production
#从库显示:Database cluster state: in archive recovery

6、检查异步流复制的情况:

可以使用主库上的视图pg_stat_replication查看流复制的信息:

postgres=# select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
  pid   |   state   | client_addr | sync_priority | sync_state 
--------+-----------+-------------+---------------+------------
 227742 | streaming | 10.255.0.64 |             0 | async
(1 row)

查看从服务(WAL接收器进程)状态:

psql -c "x" -c "SELECT * FROM pg_stat_wal_receiver;"

7、查看备库状态:

如何判断数据库处于备库状态:

1)hotstandby 状态: 可以连接数据库执行pg_is_in_recovery()函数,主库上返回False,standby上返回true;

主库:

postgres=# select pg_is_in_recovery();
pg_is_in_recovery
f 
(1 row) 

standby库:

postgres=# select pg_is_in_recovery();
pg_is_in_recovery
t
(1 row)

6.主从切换

主库停止服务

systemctl stop postgresql-12

从库执行

su postgres

sudo -i -u postgres /usr/pgsql-12/bin/pg_ctl promote -D /data/pgsql/12/data/

#waiting for server to promote… done
#server promoted

原主库添加添加standby.signal

sudo -i -u postgres touch /data/pgsql/12/data/standby.signal

原主库重启

systemctl restart postgresql-12

全备命令

pg_basebackup -h localhost -D /var/lib/pgsql/12/backups/ -Ft -R -z -v --checkpoint=fast

修改postgresql.conf

wal_level = hot_standby # 这个是设置主为wal的主机
max_wal_senders = 5 # 这个设置了可以最多有几个流复制连接,差不多有几个从,就设置几个
wal_keep_segments = 128 # 设置流复制保留的最多的xlog数目
wal_sender_timeout = 60s # 设置流复制主机发送数据的超时时间
max_connections = 200 # 一般查多于写的应用从库的最大连接数要比较大
hot_standby = on # 说明这台机器不仅仅是用于数据归档,也用于数据查询
max_standby_streaming_delay = 30s # 数据流备份的最大延迟时间
wal_receiver_status_interval = 10s # 多久向主报告一次从的状态,当然从每次数据复制都会向主报告状态,这里只是设置最长的间隔时间
hot_standby_feedback = on # 如果有错误的数据复制,是否向主进行反馈
wal_log_hints = on # also do full page writes of non-critical updates

故障的原主库,重新作为备库使用

在异步流复制(async)模式下,主库故障切换后,可能存在原主库故障时还有数据没来及的复制到备库,这些数据将丢失。(注:PostgreSQL的Streaming Replication是以事务为单位,即使数据未同步完毕,也不会出现备库某个事务只恢复一半的情况,因此事务一致性还是可以保证的。)

此种情况下,原主库的最后一个事务时间戳比复制到原备库(新主库)的事务时间戳更新。比如:倒换前最后几个事务是100/101/102,故障前流复制到100事务,则故障切换后,原主库中最新一个事务是102,原备库(新主库)中复制的最后一个事务是100,后续新主库(原备库)将在100的基础上,进行新的事务操作。原主库数据、新主库数据出现分叉点。因此,如果希望原主库恢复服务后作为新备库运行,则需要:

删库,重搭新备库(详细参考前文备库配置过程)

  1、 关闭库,并清空数据(清楚数据即可,不需要重装数据库)

    pg_ctl stop -m fast

    rm -rf /var/lib/pgsql/data/*

  2、 新备库进行数据基本备份

    pg_basebackup ….

  3、 启动新备库

    pg_ctl start

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值