PostgreSQL异步流复制环境搭建

原理:

PostgreSQl从9.0版本之后推出一个类似于Oracle的active dataguard一样的日志传送。我们借助这个功能就可实现PostgreSql的主从复制。

基本原理就是,通常一台主数据库提供读写,然后把数据同步到另一台从库。从库不断apply从主库接收到的数据,从库不提供写服务,只对外提供读服务。在postgresql中提供读写全功能的服务器称为primary database或master database,在接收主库同步数据的同时又能提供读服务的从库服务器称为hot standby server。

PostgreSQL在数据目录下的pg_xlog子目录中维护了一个WAL日志文件,该文件用于记录数据库文件的每次改变,这种日志文件机制提供了一种数据库热备份的方案,即:在把数据库使用文件系统的方式备份出来的同时也把相应的WAL日志进行备份,即使备份出来的数据块不一致,也可以重放WAL日志把备份的内容推到一致状态。这也就是基于时间点的备份(Point-in-Time Recovery),简称PITR。而把WAL日志传送到另一台服务器有两种方式,分别是:

1. WAL日志归档(base-file)

2. 流复制(streaming replication)

第一种是写完一个WAL日志后,才把WAL日志文件拷贝到standby数据库中,简言之就是通过cp命令实现远程备份,这样通常备库会落后主库一个WAL日志文件。而第二种流复制是postgresql9.x之后才提供的新的传递WAL日志的方法,它的好处是只要master库一产生日志,就会马上传递到standby库,同第一种相比有更低的同步延迟,所以我们肯定也会选择流复制的方式。

一 实验环境

二 实验步骤

2.1 安装PG数据库

在主从上都安装下PG。

可以参考https://blog.csdn.net/yabingshi_tech/article/details/78258767

不一样的是从库不需要进行 initdb 初始化数据库,且本篇文章安装的是PG 11.6版本。

2.2 创建主备同步账号

#在主库创建同步账号

$ psql

pocdb=# CREATE USER repl ENCRYPTED PASSWORD '123456' REPLICATION;

CREATE ROLE

检查创建用户的权限:

                                            | {}        |

postgres=# \du+

                                          List of roles

 Role name |                         Attributes                         | Member of | Description

-----------+------------------------------------------------------------+-----------+-------------

 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}        |

 repl      | Replication                                                | {}        |

2.3 配置主库

2.3.1 修改pg_hba.conf

cd /data/server/pgdata

vi pg_hba.conf

添加:

host    replication     repl           10.192.203.108/32       md5

意思是允许用户repl从10.192.203.108/32的网络上发起到本数据库的流复制连接,使用md5的密码认证。

2.3.2 修改postgresql.conf

listen_addresses = '*'

max_wal_senders=5

wal_level=hot_standby

2.3.3 重启主库

重启主库以使配置生效:

[postgres@ZooKeeper-node1 ~]$ pg_ctl -D /data/server/pgdata/ stop

waiting for server to shut down.... done

server stopped

[postgres@ZooKeeper-node1 ~]$ pg_ctl -D /data/server/pgdata/ start

waiting for server to start....2019-12-31 16:08:58.622 CST [16921] LOG:  listening on IPv4 address "0.0.0.0", port 5432

2019-12-31 16:08:58.622 CST [16921] LOG:  listening on IPv6 address "::", port 5432

2019-12-31 16:08:58.625 CST [16921] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"

2019-12-31 16:08:58.649 CST [16922] LOG:  database system was shut down at 2019-12-31 16:08:39 CST

2019-12-31 16:08:58.653 CST [16921] LOG:  database system is ready to accept connections

 done

server started

2.4 同步数据

#在备库远程连接主库同步数据:
pg_basebackup -h 10.192.203.107 -U repl -W -Fp -Pv -Xs -R -D /data/server/pgdata/
Password: 
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_17136"
31583/31583 kB (100%), 1/1 tablespace                                         
pg_basebackup: write-ahead log end point: 0/20000F8
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: base backup completed
同步完成后在pg_data下就能看到同步过来的相关文件了:
 
chown -R postgres:postgres pgdata
[root@ZooKeeper-node2 pgdata]# cat recovery.conf 
standby_mode = 'on'
primary_conninfo = 'user=repl password=123456 host=10.192.203.107 port=5432 sslmode=disable sslcompression=0 target_session_attrs=any'

2.5 配置从库

vi postgresql.conf

hot_standby = on

 

#启动备库:

pg_ctl -D /data/server/pgdata/ start

 

2.6 检查测试

1.在主库上创建数据库,建表,插入数据:

pocdb=# create database dan;

CREATE DATABASE



dan=# \c dan

You are now connected to database "dan" as user "postgres".

dan=# create table t(id int);

CREATE TABLE

dan=# insert into t(id) values(1);

INSERT 0 1

#在备库上检查确认

postgres=# \dan

                     List of aggregate functions

 Schema | Name | Result data type | Argument data types | Description

--------+------+------------------+---------------------+-------------

(0 rows)



postgres=# \c dan

You are now connected to database "dan" as user "postgres".

dan=# select * from t;

 id

----

  1

(1 row)

2.在主库上执行select * from pg_stat_replication;

……

 

--在备库上不允许写入数据:

dan=# insert into t(id) values(2);

ERROR:  cannot execute INSERT in a read-only transaction

 

本篇文章参考了https://www.cnblogs.com/nolanchan/p/9964831.html

《PostgreSQL 修炼之道:从小工到专家》

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值