linux实现TimescaleDB 基于异步流的主从复制
本篇文章基于上篇文章的基础上进行部署:
linux实现keepalived + TimescaleDB 的高可用实现
参考文章:
1.官方文档
2.基于 docker 的 postgres 主从流复制部署
一、介绍
TimescaleDB因为是PostgreSQL的时序性插件,所以两者的主从配置大致一样。
关于TimescaleDB,或者说PostgreSQL的主从复制大致有三种:
1.基于文件的日志传送
直接从一个数据库服务器移动WAL记录到另一台服务器被称为日志传送,PostgreSQL通过一次一文件(WAL段)的WAL记录传输实现了基于文件的日志传送。
2.流复制
流复制,就是备服务器通过tcp流从主服务器中同步相应的数据,主服务器在WAL记录产生时即将它们以流式传送给备服务器,而不必等到WAL文件被填充。
2.1 异步流复制(默认)【本文采用该方式】
会丢失最后一个事务的数据包,但性能高。
2.2 同步流复制
不会丢失数据,除非主机备机同时挂掉,性能低。
二、主机配置
此部分为主机配置:
1.启动容器
上篇文章已经基于docker-compose生成好了容器,并且我们已经修改好了密码(修改不修改对主从复制的部署影响不大)。
现在我们重启该容器即可:
查看容器id:docker ps -a
重启容器:docker restart 容器id
2.进入容器内部
docker exec -it 容器id /bin/sh
3.在容器内部,切换到postgres 用户
su postgres
4.进入postgres 客户端
psql
5.配置超级用户
SET password_encryption = 'scram-sha-256';
CREATE ROLE repuser WITH REPLICATION PASSWORD '123456' LOGIN;
注:repuser
为用户名,123456
为密码,不推荐修改用户名,密码随便改。
如果不想用scram-sha-256
加密方式,将其改为md5
,以及下面的pg_hba.conf
文件中也改为md5
。
6.配置pgpool用户
SET password_encryption = 'md5';
CREATE ROLE replication_user WITH REPLICATION PASSWORD 'md587cb5f1bfe7a883399a0b24a741e252c' LOGIN;
该pgpool用户,是为了之后配置复制的高可用,而引入的中间件pgpool-II所使用,账号密码必须如此,不可改变。
7.退出容器内部
退出postgres客户端:\q
退出postgres用户:exit
退出容器内部:exit
8.修改postgresql.conf文件
容器位置:docker-compose.yml文件中挂载在外边的地址,我的挂载地址为:/data/docker/timescaledb/data
。
当然,你也可以在容器内部修改,容器内部该文件的地址为:/var/lib/postgresql/data
。
一下内容直接附加在postgresql.conf文件上即可,别的不用动。
listen_address = "*" #该行已经有了,就不用复制了,复制下面四行到该行底下即可。
wal_level = replica
max_wal_senders = 3
max_replication_slots = 3
synchronous_commit = off
9.重启该docker容器
docker restart 容器id
10.创建复制插槽
SELECT * FROM pg_create_physical_replication_slot('replica_1_slot');
注:括号中为复制插槽名字,不建议修改。
11.配置基于主机的身份验证
# TYPE DATABASE USER ADDRESS METHOD
# "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 192.168.50.31/32 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 repuser 192.168.50.31/32 scram-sha-256
host all all all md5
我们添加了两行数据:
第一行:
# IPv4 local connections:
host all all 从机ip/32 trust
第二行:
# Allow replication connections from localhost, by a user with the
# replication privilege.
host replication repuser 从机ip/32 scram-sha-256
这里也是与官方文档不同的地方,官方文档只有这里的第二行数据,而没有第一行。
如果没有第一行数据,会在日志文件中报错:
FATA:no pg_hba.conf entry for host "192.168.50.31",user "postgres",database "postgres",SSL off
12.1 创建recovery.done文件
该文件原名recovery.conf
,当后缀变为done
时,不起作用,因为该文件是备机特有的。
这里创建该文件的原因是:为后面的主备切换做准备,当主机切换为备机后,仅把该文件的后缀由done
变为conf
,让他起作用即可。
文件地址:/data/docker/timescaledb/data
。
mkdir recovery.done
12.2 recovery.done文件内容
standby_mode = on # Ensures that the replica continues to fetch WAL records from the primary
primary_conninfo = 'host=备机ip port=5432 user=repuser password=123456'#为之前创建的超级用户的账号和密码
primary_slot_name = 'replica_1_slot' # Name of the replication slot we created on the master
12.3 修改文件权限
进入该文件同级目录,使用以下命令:
chmod 0600 recovery.done
修改完毕后,使用ls -l
命令查看权限。
原因:必须禁止非root用户的任何权限,否则该文件将被忽略。
三、备机配置
此部分为备机配置:
1.停止运行docker容器
运行docker容器,会生成自己的data数据(容器外挂载地址为:/data/docker/timescaledb/data
),容器内的地址为/var/lib/postgresql/data
。
关闭docker容器可避免反复刷新data数据,避免不必要的麻烦。
2.删除data文件
官网做法:rm -rf <DATA_DIRECTORY>/*
因为官网没有采用docker容器,所以我不建议进入docker容器用该命令删除。
我的做法:
使用三方软件:WinSCPPortable也好,Xftp也罢,直接删除挂载在外的文件即可,即直接将/data/docker/timescaledb
地址下的data文件右键删除即可。
当然,你也可以在容器外部使用rm -rf <DATA_DIRECTORY>/*
命令删除该文件夹。
3.把主机的data文件复制到备机
官网做法:
pg_basebackup -h <PRIMARY_IP> -D <DATA_DIRECTORY> -U repuser -vP -W
我的做法:
使用三方软件,WinSCPPortable或Xftp(我使用的前者)将主机的data文件
复制到本地,然后再从本地上传到备机的/data/docker/timescaledb
目录下。
4.修改recovery.conf文件
standby_mode = on # Ensures that the replica continues to fetch WAL records from the primary
primary_conninfo = 'host=主机ip port=5432 user=repuser password=123456'#为之前创建的超级用户的账号和密码
primary_slot_name = 'replica_1_slot' # Name of the replication slot we created on the master
仅将host
的内容,从备机ip修改为主机ip
。
5.修改文件权限
进入该文件同级目录,使用以下命令:
chmod 0600 recovery.conf
修改完毕后,使用ls -l
命令查看权限。
6.修改postgresql.conf文件
文件地址:/data/docker/timescaledb/data
hot_standby = on
wal_level = replica
max_wal_senders = 6
max_replication_slots = 6
synchronous_commit = off
将这五行数据,替换掉主机备份过来的四行同样的数据。
这里和主机配置文件不同的地方为:
a.max_wal_senders
和max_replication_slots
的值,备机比主机大。
b.且备机比主机多了一行数据:hot_standby = on
。
四、pg_hba.conf
配置文件问题
在主机配置的第11个步骤,我们配置了基于主机的身份验证。该配置方案对于异步流复制来说,是完全没有问题的。
但是,我们要在下一章节,配置pgpool-II + timescale的高可用方案,会与该配置文件冲突。经测试,最后不冲突(既支持异步流复制,又支持主备切换),完好的配置文件为下:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
# IPv6 local connections:
host replication repuser 0.0.0.0/0 trust
host all all all md5
host all all 0.0.0.0/0 md5
建议在此时,直接将该文件修改为此状态。
五、测试
A.官网测试方法-----View Replication Diagnostics
1.进入主机容器内部:
docker exec -it 容器id /bin/sh
su postgres
psql
2.执行命令:
执行该条命令:
select * from pg_stat_replication;
3.返回结果
如果配置正确的话,会返回如下数据:
B.校验主从配置
1.进入主机容器内部
命令三连:XXX
2.执行命令:
执行该条命令:
select client_addr,sync_state from pg_stat_replication;
3.返回结果
返回结果表示备机ip为192.168.50.31,为异步流复制。
C.数据库插入数据校验
1.使用Navicat分别连接两个数据库
2.在主机插入数据,刷新从机,看数据是否会复制到备机
同时,备机为只读,不可插入数据。
目前存在问题:主机挂了,不可往备机插入数据。