众所周知,备份对于企业数据来说是一件极为重要的事情,在实际情况中,即使拥有完善的备份策略,无论是应对人为不小心犯错,还是不可抗因素带来的数据安全隐患,也会给业务带来不少的负面影响,甚至可能包括客户流失、声誉受损或不符合服务水平协议 (SLA) 被处罚,因此我们需要一种更好liu的数据保护策略,备库(Standby Database)应运而生。
一、备库的特点
高可用
通过系统架构设计,减少减少系统不能提供服务的时间。防止主数据库机器宕掉时无法访问,备数据库服务器可以快速提升为主服务器并提供服务。
可靠性
备服务器也提供了数据库的另一个副本,当主数据库的数据丢失后,备数据库服务器上还有一份数据,不至于数据的完全丢失。
分流
主数据库和备数据库上的数据是一致,可以分担主库上一些读业务,减少主库上的资源争用。
二、PostgreSQL备库的演变路线
| 版本 | 特性 | 备注 |
| Postgresql 9.0之前 | 运程传说归档日志方式,因此备库永远比主库落后一个wal日志 | archive_command=‘scp postgres@*.*.*.*:/pgarchive%f’ |
| Postgresql 9.0 | 流复制,一有wal日志,立马传送备库,一般最多丢失几秒的数据 | |
| Postgresql 9.1 | 提供了同步复制的功能。不丢数据 | 如果一个从库的话,如果备库异常,那主库可能存在hang住的风险,所以建议使用异步模式或者一主多备的架构 |
| Postgresql 9.2 | 提供级联复制的功能 | |
| Postgresql 10 | 逻辑复制 | |
| Postgresql 12之前 | 备库模式需在数据库的数据目录下创建一个recovery.conf文件 | |
| Postgresql 12 | 备库模式需在数据库的数据目录下创建一个standby.signal文件 |
三、PostgreSQL备库的实现方式
在PostgreSQL中备库搭建的实现有两种,分别为物理复制和逻辑复制。PostgreSQL9.0出现的流复制是基于WAL日志的物理复制,其原理是主库不间断地发送WAL日志流到备库,备库接到主库发送的WAL日志后应用WAL(类似于Oracle的ADG架构实现);而逻辑复制是基于逻辑解析,其核心原理是将主库的WAL日志流解析成一定格式的数据流,订阅节点接收到解析后的WAL数据流后进行应用,从而实现数据同步。
| wal_level | 复制级别 | 本质 | 版本限制 | 是否支持过滤DML | |
| 物理复制 | replicate | 实例 | WAL物理复制 | 大版本一致 | 不支持 |
| 逻辑复制 | logical | 表 | WAL逻辑解析 | 可以跨版本 | 支持 |
四、PostgreSQL备库的类型
若备数据库在接收主数据库同步数据和应用同步数据时不能提供只读服务,则该被数据库称为 Warm Standby Server;而如果备数据库在接收和应用主数据库同步数据时也能提供只读服务,则该备数据库称为Hot Standby Server。通过参数host_standby=on/off控制。
五、Hot Standby示例
通常实际应用中建议部署异步流复制的hot standby数据库
5.1 配置环境
| 主机名 | IP地址 | 角色 | 数据目录 | 配置 |
| master | 192.168.19.192 | 主库 | /data/pg13.6/data/ | 数据库软件+实例 |
| standby | 192.168.19.193 | 备库 | /data/pg13.6/data/ | 数据库软件 |
5.2 创建复制用户
在主库创建repl用户
[postgres@master ~]$/data/pg13.6/bin/pg_ctl -D /data/pg13.6/data -l logfile start
waiting for server to start.... done
server started
[postgres@master ~]$
[postgres@master ~]$
[postgres@master ~]$ psql
psql (13.6)
Type "help" for help.
postgres=# create role repl login replication encrypted password '****';
CREATE ROLE
postgres=#
5.3 修改参数配置
修改主库监听参数及pg_hba.conf
alter system set listen_addresses = '*'; --重启服务生效
pg_hba.conf
host all all 192.168.19.0/24 md5 --允许192.168.19.0网段的机器连接
host replication repl 192.168.19.193/24 md5 --允许192.168.19.193网段的机器进行复制连接
配置完后重启数据库pg_ctl restart -mf
5.4 备库恢复
[postgres@standby data]$ pg_basebackup -h 192.168.19.192 -U repl -D /data/pg13.6/data -X stream -C --slot=node_193 -P -R
Password:
24287/24287 kB (100%), 1/1 tablespace
####启动备库######
[postgres@standby data]$ pg_ctl start -mf
waiting for server to start....2022-07-29 15:14:44.023 CST [14995] LOG: starting PostgreSQL 13.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
2022-07-29 15:14:44.024 CST [14995] LOG: listening on IPv4 address "0.0.0.0", port 5432
2022-07-29 15:14:44.024 CST [14995] LOG: listening on IPv6 address "::", port 5432
2022-07-29 15:14:44.026 CST [14995] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2022-07-29 15:14:44.032 CST [14996] LOG: database system was interrupted; last known up at 2022-07-29 15:13:34 CST
2022-07-29 15:14:44.048 CST [14996] LOG: entering standby mode
2022-07-29 15:14:44.050 CST [14996] LOG: redo starts at 0/2000028
2022-07-29 15:14:44.058 CST [14996] LOG: consistent recovery state reached at 0/2000100
2022-07-29 15:14:44.061 CST [14995] LOG: database system is ready to accept read only connections
2022-07-29 15:14:44.081 CST [15000] LOG: started streaming WAL from primary at 0/3000000 on timeline 1
done
server started
[postgres@standby data]$
5.5 验证主库同步
####主库创建一张cs表,并插入数据#####
[postgres@master ~]$ psql
psql (13.6)
Type "help" for help.
postgres=#
postgres=#
postgres=#
postgres=# create table cs(id int,name varchar(20));
CREATE TABLE
postgres=# insert into cs values(1,'zhangsan');
INSERT 0 1
postgres=# insert into cs values(2,'lisi');
INSERT 0 1
postgres=# insert into cs values(3,'wangwu');
####备库查询检验#####
[postgres@localhost data]$ psql
psql (13.6)
Type "help" for help.
postgres=# select * from cs;
id | name
----+----------
1 | zhangsan
2 | lisi
3 | wangwu
(3 rows)
postgres=#




