暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

《课程笔记 | PostgreSQL深入浅出》之构建standby(十四)

原创 布衣 2022-12-07
982

一、规划

master 192.168.84.9
slave 192.168.84.10
需求:master和slave作为主从流复制,当master宕机后,slave切换为新主继续服务;然而当master恢复故障后,作为从重新加入主从流复制。

二、部署

2.1克隆虚拟机 略
2.2创建用户

postgres=# create user rep replication password 'rep'; CREATE ROLE
复制

2.3 修改主库配置文件

postgresql.conf listen_address = '*' wal_level = replica archive_mode = on archive_command = 'cp %p /usr/local/pgsql/pgarch/%f' max_wal_senders= 10 wal_keep_segments=1024 hot_standby = on
复制

参数简要说明:
listen_address: 按需设置,本次测试配置为所有主机均可以访问,生产环境可以按需配置网段或IP等
wal_level: 设置流复制模式至少设置为replica
archive_mode: 本次启用归档
archive_command:WAL日志归档命令,生产环境可以将归档拷贝到对应目录或其他机器上,本次测试配置为归档到本机的另一个目录下
max_wal_senders: 最大WAL发送进程数,此数量需大于等于从库个数且比max_connections小。
wal_keep_segments: pg_wal目录下保留WAL日志的个数,每个WAL文件默认16M,为保障从库能在应用归档落后时依旧能追上主库,此值建议设置较大一点。
hot_standby: 此参数控制在恢复归档期间是否支持只读操作,设置为ON后从库为只读模式。

注意: 上述参数中有涉及归档日志的路径,需手动创建
mkdir -p /usr/local/pgsql/pgarch/

2.4 修改配置文件pg_hba.conf
添加复制账号的权限,因可能会主从切换,因此 主从机器的IP均添加。也可以设置网段,以便于后期添加从库。

# replication privilege. local replication all trust host replication all 127.0.0.1/32 trust host replication all ::1/128 trust host replication all 192.168.84.9/24 md5 host replication all 192.168.84.10/24 md5
复制

5、备份数据
从机上在线备份主库数据,并将数据放在指定路径,此路径建议与主库路径一致。可以使用pg_basebackup命令在线热备份,具体命令如下:

[postgres@pgstandby pgdata]$ pg_basebackup -h 192.168.84.9 -U rep -p 5432 -F p -X s -v -P -R -D /usr/local/pgsql/pgdata -l rep_backup
复制
口令:
pg_basebackup: 开始基础备份,等待检查点完成
pg_basebackup: 已完成检查点
pg_basebackup: 预写日志起始于时间点: 0/1F000028, 基于时间轴1
pg_basebackup: 启动后台 WAL 接收进程
pg_basebackup: 已创建临时复制槽"pg_basebackup_1752"
33675/33675 kB (100%), 1/1 表空间
pg_basebackup: 预写日志结束点: 0/1F000100
pg_basebackup: 等待后台进程结束流操作...
pg_basebackup: 同步数据到磁盘...


pg_basebackup: 基础备份已完成pg_basebackup命令中的参数说明:
-h 指定连接的数据库的主机名或IP地址,这里就是主库的ip
-U 指定连接的用户名,此处是我们刚才创建的专门负责流复制的repl用户
-F 指定生成备份的数据格式,支持p(plain原样输出)或者t(tar格式输出)
-X 表示备份开始后,启动另一个流复制连接从主库接收WAL日志,有 f(fetch)和s (stream)两种方式,建议使用s方式
-P 表示显示数据文件、表空间传输的近似百分比 允许在备份过程中实时的打印备份的进度
-v 表示启用verbose模式,命令执行过程中会打印各阶段日志,建议启用
-R 表示会在备份结束后自动生成recovery.conf文件,这样也就避免了手动创建
-D 指定把备份写到哪个目录,这里尤其要注意一点就是做基础备份之前从库的数据目录(/data/postgresql/data)目录需要手动清空
-l 表示指定个备份的标识,运行命令后可以看到进度提示

复制

从以上日志信息看出pg_basebackup命令首先对数据库做一次checkpoint,之后基于时间点做一个全库基准备份,全备过程中会拷贝$PGDATA数据文件和表空间文件到备库节点对应目录。

2.5 修改standby.signal

以上备份命令中生成了standby.singnal文件,因此简单修改即可。 [postgres@pgstandby pgdata]$ cat standby.signal standby_mode = ‘on’
复制

2.6 修改postgres.conf

primary_conninfo = ‘host=192.168.84.9 port=5432 user=rep password=rep’ recovery_target_timeline = ‘latest’ hot_standby = on max_standby_streaming_delay = 30s wal_receiver_status_interval = 10s hot_standby_feedback = on
复制

参数说明:
standby_mode: 设置是否启用数据库为备库,如果设置成on,备库会不停地从主库上获取WAL日志流,直到获取主库上最新的WAL日志流
primary_conninfo:设置主库的连接信息,这里设置了主库IP、端口、用户名信息等,此处是明文密码,生产环境建议配置非明文密码,而是将密码配置在另一个隐藏文件中
covery_target_timeline: 设置恢复的时间线(timeline),默认情况下是恢复到基准备份生成时的时间线,设置成latest表示从备份中恢复到最近的时间线,通常流复制环境设置此参数为latest,复杂的恢复场景可将此参数设置成其他值.
recovery_target_timeline ( ``string): 指定恢复到特定时间轴。默认设置是沿着执行基本备份时的当前时间线恢复。将此设置为 latest 将恢复到存档中找到的最新时间轴,这在备用服务器中很有用。
hot_standby” 为“on”,说明备库是“Hot Standby”,即可以只读的,如果配置“hot_standby” 为“off”,说明备库是“Warm Standby”,psql是无法连接这个备库的
max_standby_streaming_delay: 适用于WAL数据从流复制接收到。 默认值是30秒。如果不指定,则单位是毫秒。 值为-1允许待机永远等待完成查询冲突。 这个参数只能在postgresql.conf文件或服务器命令行上设置。
wal_receiver_status_interval: 备机向主机发送相关复制信息的最小频率,小于等于零说明不需要发送
hot_standby_feedback: 配置该参数之后备库会定期向主库通知最小活跃事务id(xmin)值,这样使得主库vacuum进程不会清理大于xmin值的事务。

2.7 启动从库
直接使用pg_ctl或配置服务启动从库即可。

[postgres@pgstandby pgdata]$ pg_ctl -D $PGDATA -l /tmp/logfile start 等待服务器进程启动 … 完成 服务器进程已经启动
复制
[postgres@pgstandby pgdata]$ ps -ef|grep postgres
root       2419   1339  0 23:34 pts/0    00:00:00 su - postgres
postgres   2421   2419  0 23:34 pts/0    00:00:00 -bash
postgres   3004      1  0 23:45 ?        00:00:00 /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/pgdata
postgres   3005   3004  0 23:45 ?        00:00:00 postgres: logger
postgres   3006   3004  0 23:45 ?        00:00:00 postgres: startup   recovering 000000010000000000000020
postgres   3007   3004  0 23:45 ?        00:00:00 postgres: checkpointer
postgres   3008   3004  0 23:45 ?        00:00:00 postgres: background writer
postgres   3009   3004  0 23:45 ?        00:00:00 postgres: stats collector
postgres   3010   3004  0 23:45 ?        00:00:00 postgres: walreceiver
postgres   3046   2421  0 23:46 pts/0    00:00:00 ps -ef
postgres   3047   2421  0 23:46 pts/0    00:00:00 grep --color=auto postgres

复制

三、检查

3.1 主库

postgres=# select * from pg_stat_replication; pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_ start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush _lag | replay_lag | sync_priority | sync_state | reply_time ------+----------+---------+------------------+---------------+-----------------+-------------+----------------- --------------+--------------+-----------+------------+------------+------------+------------+-----------+------ -----+------------+---------------+------------+------------------------------- 1830 | 16479 | rep | walreceiver | 192.168.84.10 | | 57638 | 2022-11-16 23:45 :42.303126+08 | 575 | streaming | 0/20000148 | 0/20000148 | 0/20000148 | 0/20000148 | | | | 0 | async | 2022-11-16 23:47:33.247604+08 (1 行记录)
复制
select pid,usesysid,usename,client_addr,state,sync_state from pg_stat_replication;
复制

image.png
3.2 从库
从库检查进程:

ps -ef |grep postgres |grep -v grep |grep receiver
复制

image.png

字段state显示的同步状态有:startup(连接中)、catchup(同步中)、streaming(同步);
字段sync_state显示的模式有:async(异步)、sync(同步)、potential(虽然现在是异步模式,但是有可能升级到同步模式)
复制

从库检查日志接受状态:

postgres=# select * from pg_stat_wal_receiver; pid | status | receive_start_lsn | receive_start_tli | received_lsn | received_tli | last_msg_send_time | last_ msg_receipt_time | latest_end_lsn | latest_end_time | slot_name | sender_host | sender_port | conninfo -----+--------+-------------------+-------------------+--------------+--------------+--------------------+------ -----------------+----------------+-----------------+-----------+-------------+-------------+---------- (0 行记录)
复制

image.png

四、测试

4.1 测试主从同步
在主库创建表并新增数据

[root@pgclass ~]# psql -h 192.168.84.9 -p 5432 -U postgres 用户 postgres 的口令: psql (11.5, 服务器 12.12) 警告:psql 主版本11,服务器主版本为12. 一些psql功能可能无法正常使用. 输入 "help" 来获取帮助信息. postgres=# \c woo psql (11.5, 服务器 12.12) 警告:psql 主版本11,服务器主版本为12. 一些psql功能可能无法正常使用. 您现在已经连接到数据库 "woo",用户 "postgres". woo=# \l 数据库列表 名称 | 拥有者 | 字元编码 | 校对规则 | Ctype | 存取权限 -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres woo | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | (4 行记录) woo=# create table rep (id int primary key, name varchar(20)); CREATE TABLE woo=# insert into rep values(1,'aaa'),(2,'abc'); INSERT 0 2 woo=#
复制

在从库查看

[postgres@PG33 data]$ psql psql (11.4) Type "help" for help. woo=# select * from rep; id | name ----+------ 1 | aaa 2 | abc (2 行记录)数据已正常同步
复制

4.2 查看复制状态
通过pg_stat_replication视图可以查看复制状态

woo=# select pid ,usesysid,usename,client_addr,state,sync_state from pg_stat_replication; pid | usesysid | usename | client_addr | state | sync_state ------+----------+---------+---------------+-----------+------------ 1830 | 16479 | rep | 192.168.84.10 | streaming | async (1 行记录)
复制

以上查询结果sync_state字段值为async,表示主备数据复制使用异步方式;state值为streaming,表示流复制方式。
4.3 调整为同步复制
前面的步骤部署的为异步复制,如想配置为同步复制,则调整recovery.conf配置文件里的 synchronous_commit及synchronous_standby_names 后重启或reload即可。

synchronous_commit = remote_write synchronous_standby_names = '*'
复制

之后再查看结果如下:

postgres=# select pid ,usesysid,usename,client_addr,state,sync_state from pg_stat_replication; pid | usesysid | usename | client_addr | state | sync_state -------+----------+---------+----------------+-----------+------------ 1830 | 16497 | repl | 192.168.84.10 | streaming | sync (1 row)
复制

此时状态已变为同步复制了。

注: synchronous_commit 有多种方式,在流复制模式下,主要设置情况如下:
remote_write: 当流复制主库提交事务时,需等待备库接收主库发送的WAL日志流并写入备节点操作系统缓存中,之后向客户端返回成功,这种情况下备库实例出现异常关闭时不会有已传送的WAL日志丢失风险,但备库操作系统异常宕机就有已传送的WAL丢失风险了,此时WAL可能还没完全写入备节点WAL文件中,简单地说remote_write表示本地WAL已落盘,备库的WAL还在备库操作系统缓存中,也就是说只有一份持久化的WAL,这个选项带来的事务响应时间较低
on: 设置成on表示流复制主库提交事务时,需等待备库接收主库发送的WAL日志流并写入WAL文件,之后才向客户端返回成功,简单地说on表示本地WAL已落盘,备库的WAL也已落盘,也就是说有两份持久化的WAL,但备库此时还没有完成重做,这个选项带来的事务响应时间较高。

remote_apply: 表示表示流复制主库提交事务时,需等待备库接收主库发送的WAL并写入WAL文件,同时备库已经完成重做,之后才向客户端返回成功,简单地说remote_apply表示本地WAL已落盘,备库WAL已落盘并且已完成重做,这个设置保证了拥有两份持久化的WAL,同时备库也完成了重做,这个选项带来的事务响应时间最高,即性能最差。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论