一、简介:Postgresql数据库的高可用使用patroni+etcd进行管理,主要功能包括:
节点监控
节点故障自动切换
old master 恢复后自动加入集群
计划性switchover
二、主机环境
考虑到所有的生产环境都是内网环境,本文的步骤均以内网环境为前提来部署安装。默认采用1主2备的模式,所以选择3台主机来举例,所有的安装步骤,在3台主机上都需要执行。
![](https://i-blog.csdnimg.cn/blog_migrate/471436195b8ef8ab07e8ee46c655177c.png)
主机IP 安装组件
10.21.10.148(master) PG13 + Patroni 2.1.2 + etcd3.3.18 + Python 3.9
10.21.10.150 PG13 + Patroni 2.1.2 + etcd3.3.18 + Python 3.9
10.21.10.151 PG13 + Patroni 2.1.2 + etcd3.3.18 + Python 3.9
--在/home/postgres下设置.pgpass,权限必须为600
#hostname:port:database:username:password
10.21.10.148:5432:all:replica:$your_passwd
#chmod 600 /home/postgres/.pgpass
三、环境搭建
3.1 安装python依赖库
为了解决python的‘_ctypes’模块找不到的问题,需要额外安装这个包
# yum install -y libffi-devel
3.2 安装Python3.9
--上传源码文件到指定目录,root用户执行
#cd /home/postgres/
#tar -zxvf Python-3.9.1.tgz
#cd Python-3.9.1
#./configure --enable-shared --不要加 --enable-optimizations,否则会导致 make 编译报错
#make
#make install
--防止找不到命令的报错: pip3: command not found
#ln -s /usr/local/bin/pip3 /usr/bin/pip3
#ln -s /usr/local/bin/python3 /bin/python3
--防止找不到库报错:python3: error while loading shared libraries: libpython3.8.so.1.0: cannot open shared object file: No such file or directory
#echo "/usr/local/lib" >> /etc/ld.so.conf.d/python_3.9.conf
#ldconfig -v
#python3 --测试安装成功
3.3 安装Python驱动psycopg2
psycopg2 的安装需要依赖 pg_config,通过RPM安装的postgresql,在升级版本的时候,需要卸载rpm包,此时可以通过变通的方式绕过,将$PG_HOME 复制到 /usr/postgres 下面,然后将setup.cfg 中的pg_config配置为/usr/postgres/app/bin/pg_config,这样 psycopg2 依赖的pg_config就不是 RPM 所安装的路径,PG 在升级版本的时候,就可以安全的进行rpm 卸载。
#mkdir -p /usr/postgres/app
#cp -R $PG_HOME/* /usr/postgres/app/
#ls -lrt /usr/postgres/app/
--修改 /etc/ld.so.conf.d/postgres.conf
#vi /etc/ld.so.conf.d/postgres.conf
>/usr/postgres/app/lib --配置lib库路径
--让配置生效
#ldconfig -v
--上传源码文件到指定目录
#cd /home/postgres/
#tar -zxvf psycopg2-2.9.3.tar.gz
#cd psycopg2-2.9.3
--修改配置文件中pg_config的路径
#vi setup.cfg
>pg_config = /usr/postgres/app/bin/pg_config
--赋权
#chmod -R 755 /usr/lib64/python*/site-packages
#chmod -R 755 /usr/lib/python*/site-packages
--安装
#python3 setup.py install
--验证安装是否成功
#python3 -c "import psycopg2; print(psycopg2.__version__)"
3.4 安装配置patroni
#cd /home/postgres
#tar -zxvf patroni_2.1.2.tar.gz
#pip3 install --no-index --find-links=file:/home/postgres/patroni_2.1.2 patroni
#pip3 install --no-index --find-links=file:/home/postgres/patroni_2.1.2 python-etcd
--检查 Patroni是否安装成功
#which patroni
#patroni -h
--配置patroni.yml
cat > /etc/patroni.yml <<EOF
# /namespace/scope/members/name
scope: prd # level 2 集群名称,统一
namespace: /postgres/ # level 1
name: node_($1,$2,$3) # level 3 需配置不同节点
restapi:
listen: 本机IP:8008 # 修改为实际ip
connect_address: 本机IP:8008 # 修改为实际ip
etcd:
hosts: 10.21.10.148:2380,10.21.10.150:2380,10.21.10.151:2380 #etcd的节点配置(client port),单节点为host,多节点为hosts,IP:PORT,并用半角逗号隔开
bootstrap:
# this section will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
# and all other cluster members will use it as a `global configuration`
#该模块一般不需修改,默认即可
dcs:
ttl: 15
loop_wait: 5
retry_timeout: 5
maximum_lag_on_failover: 1048576
master_start_timeout: 300
synchronous_mode: true
postgresql:
use_pg_rewind: true
postgresql:
listen: 10.21.10.148:5432 # 修改成实际ip和PG端口
connect_address: 10.21.10.148:5432 # 修改成实际ip和PG端口
data_dir: /data/postgres/data # 修改成实际的数据目录
bin_dir: /opt/postgres/bin # 修改成实际的安装目录
pgpass: /home/postgres/.pgpass # 修改成实际的.pgpass文件
authentication: # 修改成实际的用户名和密码
replication:
username: replica #复制用户名
password: $your_passwd #复制用户密码
superuser:
username: postgres #postgres
password: $your_passwd #postgres用户密码
parameters:
unix_socket_directories: '/tmp'
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
EOF
3.5 配置patroni的service
cat > /usr/lib/systemd/system/patroni.service <<EOF
[Unit]
Description=Runners to orchestrate a high-availability PG DATABASE
After=syslog.target network.target
[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni.yml #通过 which patroni 获取绝对路径
KillMode=process
TimeoutSec=30
Restart=no
[Install]
WantedBy=multi-user.target
EOF
--加载patroni配置
#systemctl daemon-reload
3.6 安装配置etcd
--创建etcd的数据目录
#mkdir -p /var/lib/etcd/
#cd /home/postgres/
#tar -zxvf etcd-v3.3.18-linux-amd64.tar.gz
#cd /home/postgres/etcd-v3.3.18-linux-amd64
#cp etcd /usr/bin
#cp etcdctl /usr/bin
--检查 etcd 是否安装成功
#which etcd
#which etcdctl
--配置etcd的conf.yml
#mkdir /etc/etcd
--以下参数不同节点配置有区别,name每个节点均不同,映射关系可以根据initial-cluster里面的配置定,需要替换成etcd所在主机的ip
cat > /etc/etcd/conf.yaml <<EOF
#配置不同节点名称
name: etcd-$1,$2,$3
#数据目录
data-dir: /var/lib/etcd/data
#本机IP
listen-client-urls: http://10.21.10.148:2379,http://127.0.0.1:2379
advertise-client-urls: http://10.21.10.148:2379,http://127.0.0.1:2379
listen-peer-urls: http://10.21.10.148:2380
initial-advertise-peer-urls: http://10.21.10.148:2380
#三个节点均要配置,注意节点名称对应
initial-cluster: etcd-1=http://10.21.10.148:2380,etcd-2=http://10.21.10.150:2380,etcd-3=http://10.21.10.151:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new
EOF
3.7 配置etcd的service
cat > /usr/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
#如下配置which etcd的绝对路径
ExecStart=/bin/etcd --config-file=/etc/etcd/conf.yaml
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
--以service的方式启动etcd
#systemctl daemon-reload
#systemctl restart etcd
#systemctl status etcd
--查看etcd节点的状态
#systemctl status etcd
--在3台主机的etcd均配置完毕后,可以检查etcd集群的状态
#etcdctl member list
3.8 搭建备库
--创建复制用户
postgres=# create role replica with login replication password '$your_passwd';
--生成基础备份,在备库各自所在的节点运行
#pg_basebackup -D /data/postgres/data -Fp -R -Xs -v -P -h $主库IP -p $主库端口 -U replica
四、日常使用及维护操作
--以service的方式启动patroni
#systemctl start patroni
#systemctl status patroni –l
--查看patroni的日志(在系统日志中)
#tail -f /var/log/messages
-- patronictl 查看集群信息
patronictl -c /etc/patroni.yml list
--修改配置
export EDITOR=vi
patronictl -c /etc/patroni.yml edit-config $集群名称
--重启集群
patronictl -c /etc/patroni.yml restart $集群名称
--重启节点
patronictl -c /etc/patroni.yml restart $集群名称 $节点名称