pg流复制

一.异步流复制

1.创建用于流复制的角色(在主备节点)


# 创建用于流复制的角色
[root@cdhslave01 pgdata]# su - postgres
[postgres@cdhslave01 ~]$ psql
postgres=#create role replica login replication encrypted password 'replica';

在主库

2.修改pg_hba.conf

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
host    all             all             0.0.0.0/0               password
#host    all             postgres             192.168.108.0/22     trust
#host    all             postgres             192.168.110.0/22     trust
host    all             replica             192.168.110.0/22     trust
host    all             replica             192.168.108.0/22     trust

# IPv6 local connections:
host    all             all             ::1/128                 trust

# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
#host    replication     postgres            192.168.108.0/22    md5
#host    replication     postgres            192.168.110.0/22    md5
host    replication     replica            192.168.110.0/22    md5
host    replication     replica            192.168.108.0/22    md5

 

3.修改postgresql.conf

wal_level = replica

max_wal_senders = 10

wal_keep_segments = 64

archive_mode = on

archive_command = 'cp %p /var/lib/pgsql/pg_archive/%f'

wal_log_hints = on

full_page_writes = on

hot_standby = on

# 用于同步复制流
#synchronous_standby_names = 'standby01,standby02'

4.创建pg_archive目录

mkdir -p /var/lib/pgsql/pg_archive

chown -R postgres:postgres  /var/lib/pgsql/pg_archive

5.启动

[root@cdhmaster01 pgdata]# su - postgres
[postgres@cdhmaster01 ~]$ pg_ctl start -D $PGDATA
[postgres@cdhmaster01 pgdata]$ pg_controldata $PGDATA
pg_control version number:            1002
Catalog version number:               201707211
Database system identifier:           6719647834413202808
Database cluster state:               in production

从库

[postgres@cdhmaster01 ~]$ cd /home
# 全量备份
[root@cdhmaster01 home]# pg_basebackup -h 192.168.108.183 -U replica -F p -Xs -P -R -D ./backup -l test20190802
Password:
58354/58354 kB (100%), 1/1 tablespace

[postgres@cdhmaster01 home]$ ls
backup  data  postgres
[root@cdhmaster01 home]# chown -R postgres:postgres ./backup
[root@cdhmaster01 home]# cd backup/
[root@cdhmaster01 backup]# vi recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=replica password=replica host=192.168.108.183 port=5432 sslmode=disable sslcompression=1 target_session_attrs=any'
trigger_file = '/home/trigger'
[root@cdhmaster01 home]# su - postgres
[postgres@cdhmaster01 ~]$ pg_ctl start -D /home/backup/
[postgres@cdhmaster01 ~]$ pg_controldata /home/backup/
pg_control version number:            1002
Catalog version number:               201707211
Database system identifier:           6719647834413202808
Database cluster state:               in archive recovery

从库提升为主库

1.主库宕机

[postgres@cdhmaster01 data]$ pg_ctl stop -D $PGDATA

2. 从库

# 提升为主库
[root@cdhmaster01 home]# su - postgres
[postgres@cdhmaster01 ~]$ pg_ctl promote -D /home/backup/
[postgres@cdhmaster01 ~]$ pg_controldata /home/backup/
pg_control version number:            1002
Catalog version number:               201707211
Database system identifier:           6719647834413202808
Database cluster state:               in production

3. 主库变为从库

[postgres@cdhmaster01 ~]$ cd /home
# 全量备份
[root@cdhmaster01 home]# pg_basebackup -h 192.168.110.31 -U replica -F p -Xs -P -R -D ./backup -l test20190802
Password:
58354/58354 kB (100%), 1/1 tablespace

[postgres@cdhmaster01 home]$ ls
backup  data  postgres
[root@cdhmaster01 home]# chown -R postgres:postgres ./backup
[root@cdhmaster01 home]# cd backup/
[root@cdhmaster01 backup]# vi recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=replica password=replica host=192.168.110.31 port=5432 sslmode=disable sslcompression=1 target_session_attrs=any'
trigger_file = '/home/trigger'

[root@cdhmaster01 home]# su - postgres
[postgres@cdhmaster01 ~]$ pg_ctl start -D /home/backup/
[postgres@cdhmaster01 ~]$ pg_controldata /home/backup/
pg_control version number:            1002
Catalog version number:               201707211
Database system identifier:           6719647834413202808
Database cluster state:               in archive recovery

查看主从情况

select * from pg_stat_replication

 select pg_is_in_recovery();

----------------------------------------------------------------------------------

一键配置脚本

下面是异步流复制脚本一键配置:

1. 一主一从

主:192.168.108.183

从:192.168.110.31

异步流复制之主库一键配置脚本

[root@cdhmaster01 pgslave]# cat master_config.sh

# 异步流复制主库一键配置脚本

# pg数据库目录
pgdata=/home/data/pgdata
# pg配置文件
pg_hba_file=pg_hba.conf
pg_postgresqlconf_file=postgresql.conf
# 归档目录
pg_archive_dir=/var/lib/pgsql/pg_archive
# 主从主机IP
master_ipo=192.168.108.0
slave_ipo=192.168.110.0
# 创建专用于复制的角色
su - postgres <<EOF
       psql;
       create role replica login replication encrypted password 'replica';
EOF

# 修改pg_hba.conf
echo "host    replication     replica            ${master_ipo}/22    md5">>${pgdata}/${pg_hba_file}
echo "host    replication     replica            ${slave_ipo}/22    md5">>${pgdata}/${pg_hba_file}

# 修改postgresql.conf
# csvlog配置,用于记录运行日志 这里主要用来监控主库
echo "log_destination = 'csvlog'">>${pgdata}/${pg_postgresqlconf_file}
echo "logging_collector = on">>${pgdata}/${pg_postgresqlconf_file}
echo "log_directory = 'pg_log'">>${pgdata}/${pg_postgresqlconf_file}
echo "log_statement ='mod'">>${pgdata}/${pg_postgresqlconf_file}
echo "log_filename = '%Y%m%d_postgresql_log'">>${pgdata}/${pg_postgresqlconf_file}
echo "log_rotation_age = 1d">>${pgdata}/${pg_postgresqlconf_file}
echo "log_truncate_on_rotation  = off">>${pgdata}/${pg_postgresqlconf_file}
echo "log_rotation_size = 2047MB">>${pgdata}/${pg_postgresqlconf_file}

# wal日志配置,用于流复制
echo "wal_level = replica">>${pgdata}/${pg_postgresqlconf_file}
echo "max_wal_senders = 10">>${pgdata}/${pg_postgresqlconf_file}
echo "wal_keep_segments = 64">>${pgdata}/${pg_postgresqlconf_file}
echo "archive_mode = on">>${pgdata}/${pg_postgresqlconf_file}
echo "archive_command = 'cp %p /var/lib/pgsql/pg_archive/%f'">>${pgdata}/${pg_postgresqlconf_file}
echo "wal_log_hints = on">>${pgdata}/${pg_postgresqlconf_file}
echo "full_page_writes = on">>${pgdata}/${pg_postgresqlconf_file}
echo "hot_standby = on">>${pgdata}/${pg_postgresqlconf_file}

# 创建pg归档目录
mkdir -p /var/lib/pgsql/pg_archive
chown -R postgres:postgres  /var/lib/pgsql/pg_archive

# 重载当前数据库(尽量不重启pg_ctl restart -D $pgdata)
su - postgres <<EOF
     pg_ctl reload -D $PGDATA
EOF

异步流复制之从库一键配置脚本(兼容主库手动切换为备库脚本)

[root@cdhmaster01 pgslave]# cat pgslave_config.sh
# 当前正常运行的主库的IP
host=192.168.110.31
# 备份别名
bak_label=test20190802
# 用于复制流的pg用户
replica_role=replica
# 从库的PG数据库目录
pgdata=/home/backup
# trigger文件目录
trigger_dir=/home/trigger

# 提示输入密码的时候输入:replica
pg_basebackup -h ${host} -U ${replica_role} -F p -Xs -P -R -D ${pgdata} -l ${bak_label}
# 为目录授权
chown -R postgres:postgres ${pgdata}
# 配置recovery.conf
if [ -f ${pgdata}/recovery.done ];then
   mv -f ${pgdata}/recovery.done ${pgdata}/recovery.conf
   sed -i "/^primary_conninfo/d" ${pgdata}/recovery.conf
   echo "primary_conninfo='user=replica password=replica host=${host} port=5432 sslmode=disable sslcompression=1 target_session_attrs=any'">>${trigger_dir}/recovery.conf
fi
# 增加触发器配置
echo "trigger_file = '${trigger_dir}'">>${pgdata}/recovery.conf
# 启动从数据库
su - postgres <<EOF
       pg_ctl start -D ${pgdata}
EOF

异步流复制之从库自动切换为主库 脚本

[root@cdhmaster01 pgslave]# vi checkMasterRun.sh

#!/bin/bash

# 检测主库是否正常运行,如果宕机了,则立即启用当前备库。
# 指定crontab 定时检测即可

time_today=`date -d "today" +"%Y%m%d"`
current_time=`date -d "today" +"%Y-%m-%d %H:%M:%S"`
# pg数据库日志
pg_logdir=/home/backup/pg_log
pg_logname=${time_today}_postgresql_log.csv
# pg数据目录
pgdata=/home/backup
# 本脚本执行日志
log_dir=/home/pgslave/checklog
log_file_name=${time_today}.log

# 创建日志目录
if [ ! -d ${log_dir} ]; then
  mkdir -p ${log_dir}
fi

echo "">> ${log_dir}/${log_file_name}
echo "---------------------start--------------------------">> ${log_dir}/${log_file_name}
echo "本次执行开始时间:${current_time}" >> ${log_dir}/${log_file_name}

# 获取本机IP
local_ip=`hostname -i|awk '{print $1}'`
echo "本机IP:${local_ip}">> ${log_dir}/${log_file_name}

# 获取备库日志中主库挂掉的日志信息
errmsg=`cat ${pg_logdir}/${pg_logname}|grep 'could not connect to the primary server'`

trigger_file=/home/trigger

if [ "$errmsg" != "" ];then
   echo "PG主库挂了,自动开始切换到备库,请等待...!">> ${log_dir}/${log_file_name}
   touch $trigger_file
   sleep 10
   recovery_comlete=`cat ${pg_logdir}/${pg_logname}|grep 'archive recovery complete'`
   if [ "${recovery_comlete}" != "" ];then
      echo "备库自动升级为主库成功! 请切换数据库连接到备库,备库IP为:${local_ip} 备库PG数据目录为:${pgdata} ">> ${log_dir}/${log_file_name}
      # 删除日志中包括could not connect to the primary server的行
      sed -i '/could not connect to the primary server/d' ${pg_logdir}/${pg_logname}
   else
      echo "备库升级为主库失败,请前往备库所在节点切换到postgres用户 执行命令:pg_ctl promote -D ${pgdata} 手动切换备库为主库!">> ${log_dir}/${log_file_name}
   fi
   rm -rf ${trigger_file}
else
  echo "主库运行正常.">> ${log_dir}/${log_file_name}
fi

current_time=`date -d "today" +"%Y-%m-%d %H:%M:%S"`
echo "本次执行结束时间:${current_time}">>${log_dir}/${log_file_name}
echo "---------------------end----------------------------" >> ${log_dir}/${log_file_name}
echo "">> ${log_dir}/${log_file_name}

二. 同步流复制

1. 一主双从

主:192.168.108.183

从:192.168.110.31/32

主库一键配置脚本

mkdir -p /home/pgslave
[root@cdhmaster01 pgslave]# cat master_config.sh

# 异步流复制主库一键配置脚本

# pg数据库目录
pgdata=/home/data/pgdata
# pg配置文件
pg_hba_file=pg_hba.conf
pg_postgresqlconf_file=postgresql.conf

# 主从主机IP网段
master_ipo=192.168.108.0
slave_ipo=192.168.110.0

# 创建专用于复制的角色
su - postgres <<EOF
       psql;
       create role replica login replication encrypted password 'replica';
EOF

# 修改pg_hba.conf
echo "host    replication     replica            ${master_ipo}/22    md5">>${pgdata}/${pg_hba_file}
echo "host    replication     replica            ${slave_ipo}/22    md5">>${pgdata}/${pg_hba_file}

# 修改postgresql.conf

# wal日志配置,用于流复制
echo "synchronous_standby_names = 'standby01,standby02'">>${pgdata}/${pg_postgresqlconf_file}

echo "wal_level = replica">>${pgdata}/${pg_postgresqlconf_file}
echo "max_wal_senders = 10">>${pgdata}/${pg_postgresqlconf_file}


# 重载当前数据库(尽量不重启pg_ctl restart -D $pgdata)
su - postgres <<EOF
     pg_ctl reload -D $PGDATA
EOF

从库一键配置

mkdir -p /home/pgslave
[root@cdhmaster01 pgslave]# cat asynpgslave_config.sh
# 当前正常运行的主库的IP
host=192.168.108.183
# 备份别名
bak_label=test20190805
# 用于复制流的pg用户
replica_role=replica
# 从库的PG数据库目录
pgdata=/home/backup
# application_name
application_name=standby01
# trigger文件目录
trigger_dir=/home/trigger
# 提示输入密码的时候输入:replica
pg_basebackup -h ${host} -U ${replica_role} -F p -Xs -P -R -D ${pgdata} -l ${bak_label}
# 为目录授权
chown -R postgres:postgres ${pgdata}
# 配置recovery.conf
if [ -f ${pgdata}/recovery.done ];then
   mv -f ${pgdata}/recovery.done ${pgdata}/recovery.conf
   sed -i "/^primary_conninfo/d" ${pgdata}/recovery.conf
   echo "primary_conninfo='application_name=${application_name} user=replica password=replica host=${host} port=5432 sslmode=disable sslcompression=1 target_session_attrs=any'">>${pgdata}/recovery.conf
else
  sed -i "/^primary_conninfo/d" ${pgdata}/recovery.conf
  echo "primary_conninfo='application_name=${application_name} user=replica password=replica host=${host} port=5432 sslmode=disable sslcompression=1 target_session_attrs=any'">>${pgdata}/recovery.conf

fi
# 增加触发器配置
echo "trigger_file = '${trigger_dir}'">>${pgdata}/recovery.conf
# 启动从数据库
su - postgres <<EOF
       pg_ctl start -D ${pgdata}
EOF

查看是否配置成功

总结:

1.异步的优点:当异步复制slave宕机,master读写不受影响,恢复后可即时同步到最新数据;

同步复制的话,如果是执行隐式事务(增删改sql),用于同步的所有slave宕机,事务挂起 master 受影响,slave恢复后master写事务继续执行,但是只要有一个slave没宕机,master就能正常运行;

如果是显式事务(带begin end的存储过程等),在slave宕机的情况下,提交的事务会(在master)本地提交,slave恢复后会将master上本地提交的事务同步到slave,rollback的事务在slave宕机时不受影响。

2. 异步的缺点是:实时性没有同步高,在同步的时候有可能还没同步完master挂了,会有丢失数据的风险,不能保证和主库完全一致。

同步流复制 可以重启的方案

1.主库配置

[root@cdhmaster01 pgslave]# cat master_config.sh

# 异步流复制主库一键配置脚本

# pg数据库目录
pgdata=/home/data/pgdata
# pg配置文件
pg_hba_file=pg_hba.conf
pg_postgresqlconf_file=postgresql.conf
# 归档目录
pg_archive_dir=/var/lib/pgsql/pg_archive
# 主从主机IP
master_ipo=192.168.108.0
slave_ipo=192.168.110.0
# 创建专用于复制的角色
su - postgres <<EOF
       psql;
       create role replica login replication encrypted password 'replica';
EOF

# 修改pg_hba.conf
echo "host    replication     replica            ${master_ipo}/22    md5">>${pgdata}/${pg_hba_file}
echo "host    replication     replica            ${slave_ipo}/22    md5">>${pgdata}/${pg_hba_file}

# 修改postgresql.conf
# csvlog配置,用于记录运行日志 这里主要用来监控主库
echo "log_destination = 'csvlog'">>${pgdata}/${pg_postgresqlconf_file}
echo "logging_collector = on">>${pgdata}/${pg_postgresqlconf_file}
echo "log_directory = 'pg_log'">>${pgdata}/${pg_postgresqlconf_file}
echo "log_statement ='mod'">>${pgdata}/${pg_postgresqlconf_file}
echo "log_filename = '%Y%m%d_postgresql_log'">>${pgdata}/${pg_postgresqlconf_file}
echo "log_rotation_age = 1d">>${pgdata}/${pg_postgresqlconf_file}
echo "log_truncate_on_rotation  = off">>${pgdata}/${pg_postgresqlconf_file}
echo "log_rotation_size = 2047MB">>${pgdata}/${pg_postgresqlconf_file}

# wal日志配置,用于流复制
echo "wal_level = replica">>${pgdata}/${pg_postgresqlconf_file}
echo "max_wal_senders = 10">>${pgdata}/${pg_postgresqlconf_file}
echo "wal_keep_segments = 64">>${pgdata}/${pg_postgresqlconf_file}
echo "archive_mode = on">>${pgdata}/${pg_postgresqlconf_file}
echo "archive_command = 'cp %p /var/lib/pgsql/pg_archive/%f'">>${pgdata}/${pg_postgresqlconf_file}
echo "wal_log_hints = on">>${pgdata}/${pg_postgresqlconf_file}
echo "full_page_writes = on">>${pgdata}/${pg_postgresqlconf_file}
echo "hot_standby = on">>${pgdata}/${pg_postgresqlconf_file}

# 创建pg归档目录
mkdir -p /var/lib/pgsql/pg_archive
chown -R postgres:postgres  /var/lib/pgsql/pg_archive

# 重载当前数据库(尽量不重启pg_ctl restart -D $pgdata)
su - postgres <<EOF
     pg_ctl reload -D $PGDATA
EOF

PG 归档

 1. 主备库postgres用户免密登录
 su - postgres
 [postgres@cdhmaster01 ~]$ ssh-keygen -t rsa
[postgres@cdhmaster01 ~]$ ssh-copy-id postgres@192.168.108.74
[postgres@cdhmaster01 ~]$ ssh-copy-id postgres@192.168.1110.42
[postgres@cdhmaster01 ~]$ ssh postgres@192.168.108.74
Last login: Tue Aug  6 10:52:41 2019 from 192.168.110.42
[postgres@cdhmaster01 ~]$ ssh postgres@192.168.110.42
Last login: Tue Aug  6 10:53:44 2019 from 192.168.108.74

2. 主备库创建归档目录
# 归档目录
pg_archive=/var/lib/pgsql/pg_archive

# 创建pg归档目录
mkdir -p ${pg_archive}
chown -R postgres:postgres ${pg_archive}

3. 主库创建replica角色
su - postgres <<EOF
       psql;
       create role replica login replication encrypted password 'replica';
EOF

4.主库修改pg_hba.conf以使得replica角色可以在备库远程进行基础备份
host    replication     replica            192.168.108.0/22    md5
host    replication     replica            192.168.110.0/22    md5

5. 主库修改postgresql.conf以使得可以进行归档
wal_level = replica
archive_mode = on
archive_command ='cp %p /var/lib/pgsql/pg_archive/%f;scp %p postgres@192.168.108.74:/var/lib/pgsql/pg_archive/%f;ssh postgres@192.168.108.74 chown -R postgres:postgres /var/lib/pgsql/pg_archive;'

6. 在备库执行基础备份
pg_basebackup -h 192.168.110.42 -U replica -F p -Xs -P -R -D /home/backup -l test20190806

7.进入/home/backup 修改recovery.conf
#standby_mode = 'on'
#primary_conninfo = 'user=replica password=replica host=192.168.110.42 port=5432 sslmode=disable sslcompression=1 target_session_attrs=any'
restore_command ='cp /var/lib/pgsql/pg_archive/%f %p'
recovery_target_time = '2019-08-06 11:35:07'

修改备库postgresql.conf
屏蔽以下两行
#archive_mode = on
#archive_command ='cp %p /var/lib/pgsql/pg_archive/%f;scp %p postgres@192.168.108.74:/var/lib/pgsql/pg_archive/%f;ssh postgres@192.168.108.74 chown -R postgres:postgres /var/lib/pgsql/pg_archive;'
 
7. 修改备库PGDATA(/home/backup)所属用户组及用户
chown -R postgres:postgres /home/backup

8. 主库手动checkpoint 几次
先插数据再执行select pg_switch_wal()


9. 查看备库/var/lib/pgsql/pg_archive是否有新文件

10.编辑备库recovery.conf,指定recovery_target_time为某个还原时间点
recovery_target_time = '2019-08-05 20:50:15'

11.启动备库
su - postgres 
pg_ctl restart -D /home/backup/
 pg_ctl stop -D /home/backup/
 12.查看是否还原成功

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值