5、pgpool-II高可用性(一)数据库的高可用性
一、实现原理
使用 pgpool-II 软件;我们常用来实现流复制的高可用性;备库只读的,不可写;就是当主库出现问题时;需要把备库自动激活为主库;来接管服务。
这在其他高可用软件也有这功能,而 pgpool-II 在配置文件 pgpool.conf 中提供配置项 failover_command 。让用户配置一个脚本,当发生故障切换时,执行该脚本。
二、示例演练
本示例采用 PostgreSQL12 + pgpool-II4。
演练目的:
- 搭建 pgpool 集群
- 测试数据库的高可用性
- 修复 primary 节点重新加入集群
2.1、环境规划
1、PostgreSQL库的IP/Port规划
| 主机名 | 角色 | ip | 端口 | 数据目录 | |
|---|---|---|---|---|---|
| node3 | pgpool | 192.168.1.221 | 9999 | ||
| node3 | primary | 192.168.1.221 | 6000 | /data1/postgres/data | |
| node4 | standby | 192.168.1.202 | 6000 | /data1/postgres/data |
2、数据库用户规划
| 用户 | 密码 | 用途详情 |
|---|---|---|
| postgres | 123456 | 用于在线恢复 |
| replica | replica | 流复制用户 |
| pgpool | 123456 | Pgpool-II health check (health_check_user) replication delay check (sr_check_user) |
2.2、数据库环境准备
1、安装 PostgreSQL 软件
N/A
2、安装 pgpool-II 软件
查看 《 pgpool-II安装 》
本示例涉及到在线恢复;需要安装 pgpool_recovery
-- 在 primary 操作
psql -c "create extension pgpool_recovery" template1
3、配置 PostgreSQL 数据库
primary 节点操作
创建数据库用户
alter user postgres password '123456';
CREATE ROLE pgpool WITH LOGIN password '123456';;
CREATE ROLE replica WITH REPLICATION LOGIN password 'replica';
--If you want to show "replication_state" and "replication_sync_state" column in SHOW POOL NODES command result, role pgpool needs to be PostgreSQL super user or or in pg_monitor group (Pgpool-II 4.1 or later)
GRANT pg_monitor TO pgpool;
配置归档
搭建流复制是不需要配置归档;但是在线恢复需要归档日志。
$ mkdir /data1/archivedir
$ vi postgresql.conf
archive_mode = on
archive_command = 'cp %p /data1/archivedir/%f'
wal_log_hints = on
4、搭建流复制
--在 standby 操作
# 用 root 操作系统用户在202创建PostgreSQL工作目录
mkdir -p /data1/postgres/data
chown -R postgres:postgres /data1/postgres/data
chmod 700 /data1/postgres/data
# 用 postgres 操作系统用户执行 pg_basebackup 命令;进行备库拷贝
pg_basebackup -F p -R --progress -D /data1/postgres/data -h 192.168.1.221 -p 6000 -U replica
# 用 postgres 操作系统户用启动备库
pg_ctl start
5、配置 ssh 互信
在上面讲到的 实现原理,使用Pgpool-II的自动故障转移和在线恢复;需要 pgpool 服务免密码在各个机器上执行;以及后续在在线恢复功能;这里我们使用 postgres 操作用户。
-- 在pgpool节点执行
$ cd ~/.ssh
$ ssh-keygen -t rsa -f id_rsa_pgpool
$ ssh-copy-id -i id_rsa_pgpool.pub postgres@node3
$ ssh-copy-id -i id_rsa_pgpool.pub postgres@node4
-- 验证免密码登录
ssh postgres@serverX -i ~/.ssh/id_rsa_pgpool
6、配置 pgpool
可以查考 《 pgpool 配置 》;这里我们是用 postgres 操作用户进行安装
配置环境变量
export PGHOME=/opt/pg12
export PGDATA=/data1/postgres/data
export PGPOOLHOME=/opt/pgpool
export PATH=$PGHOME/bin:$PATH:$HOME/bin:$PGPOOLHOME/bin
1、设置 pcp 的管理用户/密码文件 pcp.conf
“pcpadm/pgpool123”
#1 进入配置目录
[postgres@node3 ~]$ cd /opt/pgpool/etc
[postgres@node3 etc]$ cp pcp.conf.sample pcp.conf
# 在该文件中;用户/密码出现在每一行; # USERID:MD5PASSWD
#2 pg_md5 生成配置的用户名密码是 pgpool123
[postgres@node3 etc]$ pg_md5 pgpool123
fa039bd52c3b2090d86b0904021a5e33
#3 编辑pcp.conf;这里配置用户是 pcpadm,
[postgres@node3 etc]$ vi pcp.conf
# USERID:MD5PASSWD
pcpadm:fa039bd52c3b2090d86b0904021a5e33
2、配置 pool_hba.conf
用于认证用户登录方式,如客户端IP限制等,类似于postgresql的pg_hba.conf文件
[postgres@node3 ~]$ cd /opt/pgpool/etc/
[postgres@node3 etc]$ vi pool_hba.conf
# 添加下面内容
host all all 0.0.0.0/0 md5
3、生成 pool_passwd
pgpool 密钥文件;通过 pgpool 访问需要用户验证;
这里暂用数据库用户 pgpool
[postgres@node3 ~]$ cd /opt/pgpool/etc/
[postgres@node3 etc]$ pg_md5 --md5auth -u pgpool -p
password:
[postgres@node3 etc]$ ll pool_passwd
-rw-r--r--. 1 postgres postgres 132 Nov 30 10:43 pool_passwd
4、配置.pgpass
使用pgpool-II进行故障库自动切换(failover)、或在线恢复(online recovery)(在线恢复:主库故障后切换,原主库恢复后变更为备库。注意是 Online recovery,而不是自动恢复,需要手工执行命令恢复),需要能够无密码 SSH 访问其他 PostgreSQL 服务器。为了满足此条件,我们需要在每个 PostgreSQL 服务器上,在 postgres 用户的 home file下创建了.pgpass 文件,并修改器文件权限为600
# su - postgres
$ vi /var/lib/pgsql/.pgpass
server1:5432:replication:repl:<repl user password>
server2:5432:replication:repl:<repl user passowrd>
server3:5432:replication:repl:<repl user passowrd>
$ chmod 600 /var/lib/pgsql/.pgpass
若设置 pg_hba.conf 的该网段免密码验证 trust;可以忽略该步骤
host replication replica 192.168.1.0/24 trust
5、配置 pcp 的 .pcppass
需要 follow_master_command 脚本情况下,由于此脚本必须在不输入密码的情况下执行pcp命令,所以我们在 postgres 用户的home directory下创建.pcppass
# echo 'localhost:9898:pgpool:pgpool' > ~/.pcppass
# chmod 600 ~/.pcppass
6、配置pgpool.conf
listen_addresses = '*'
port = 9999
backend_hostname0 = '192.168.1.221'
backend_port0 = 6000
backend_weight0 = 1
backend_data_directory0 = '/data1/postgres/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = 'server0'
backend_hostname1 = '192.168.1.202'
backend_port1 = 6000
backend_weight1 = 1
backend_data_directory1 = '/data1/postgres/data'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = 'server1'
enable_pool_hba = on
pool_passwd = 'pool_passwd'
pid_file_name = '/opt/pgpool/pgpool.pid'
logdir = '/opt/pgpool'
replication_mode = off
load_balance_mode = on
master_slave_mode = on
master_slave_sub_mode = 'stream'
sr_check_period = 10
sr_check_user = 'pgpool'
sr_check_password = '123456'
sr_check_database = 'postgres'
delay_threshold = 10000000
health_check_period = 5
health_check_user = 'pgpool'
health_check_password = '123456'
health_check_database = 'postgres'
health_check_max_retries = 3
failover_command = '/opt/pgpool/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'
# If we use 3 PostgreSQL servers, we need to specify follow_primary_command to run after failover on the primary node failover.
# In case of two PostgreSQL servers, follow_primary_command setting is not necessary
# follow_primary_command = '/opt/pgpool/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'
# online recovery
recovery_user = 'postgres'
recovery_password = '123456'
recovery_1st_stage_command = ''
recovery_2nd_stage_command = ''
recovery_timeout = 90
7、配置 failover_command 脚本
[postgres@node3 ~]$ cd $PGPOOLHOME
[postgres@node3 pgpool]$ cp etc/failover.sh.sample failover.sh
[postgres@node3 pgpool]$ vi failover.sh
修改变量 PGHOME
[postgres@node3 pgpool]$ chmod +x failover.sh
2.3、启动 pgpool
[postgres@node3 ~]$ pgpool -n > /tmp/pgpool.log &
[postgres@node3 ~]$ psql -p 9999 postgres pgpool
2020-12-01 14:50:09: pid 2422: LOG: new connection received
2020-12-01 14:50:09: pid 2422: DETAIL: connecting host=[local]
psql (12.2)
Type "help" for help.
postgres=> show pool_nodes;
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_syn
c_state | last_status_change
---------+---------------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+----------------
--------+---------------------
0 | 192.168.1.221 | 6000 | up | 0.500000 | primary | 0 | false | 0 | |
| 2020-12-01 14:38:09
1 | 192.168.1.202 | 6000 | up | 0.500000 | standby | 0 | true | 0 | |
| 2020-12-01 14:38:09
(2 rows)
2.4、测试高可用性
1、备份自动激活为主库
我们先把主库停掉,看看备库是否可以激活为主库;
[postgres@node3 ~]$ pg_ctl stop
waiting for server to shut down..... done
server stopped
# 再次查看节点信息
[postgres@node3 ~]$ psql -p 9999 postgres pgpool
2020-12-01 14:53:57: pid 2591: LOG: new connection received
2020-12-01 14:53:57: pid 2591: DETAIL: connecting host=[local]
psql (12.2)
Type "help" for help.
postgres=> show pool_nodes;
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_syn
c_state | last_status_change
---------+---------------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+----------------
--------+---------------------
0 | 192.168.1.221 | 6000 | down | 0.500000 | standby | 0 | false | 0 | |
| 2020-12-01 14:53:07
1 | 192.168.1.202 | 6000 | up | 0.500000 | primary | 0 | true | 0 | |
| 2020-12-01 14:53:07
(2 rows)
测试结果: 备库成功激活为新主库
从上面的查询结果可以看到 “node_id=1”的 role 变成了 “primary”
2、原主库重加回集群
现在我们把原主库加回集群,变成备库。后面再演示 online recovery。先手动执行
1、同步时间线
202 备库提升为新主库;其时间线 +1;与 221 不同步;这是需要使用pg_rewind同步数据
[postgres@node3 ~]$ pg_rewind --target-pgdata $PGDATA --source-server='host=192.168.1.202 port=6000 user=postgres dbname=postgres password=123456'
pg_rewind: servers diverged at WAL location 0/18000000 on timeline 1
pg_rewind: rewinding from last common checkpoint at 0/17000148 on timeline 1
pg_rewind: Done!
2、配置 postgresql.conf
# 192.168.1.221
$ cd $PGDATA
$ touch standby.signal
$ vi postgresql.conf
primary_conninfo = 'host=192.168.1.202 port=6000 user=replica'
3、启动 postgresql
[postgres@node3 ~]$ pg_ctl start
后续讲解online recovery。未完待续...
5、pgpool-II高可用性(一)数据库的高可用性的更多相关文章
- 【SQL Server高可用性】数据库复制:SQL Server 2008R2中数据库复制
经常在论坛中看到有人问数据同步的技术,如果只是同步少量的表,那么可以考虑使用链接服务器+触发器,来实现数据同步,但当要同步的数据表比较多,那么可以考虑用数据库复制技术,来实现数据的同步. 一.使用场景 ...
- 【SQL Server高可用性】数据库复制:SQL Server 2008R2中通过数据库复制,把A表的数据复制到B表
原文:[SQL Server高可用性]数据库复制:SQL Server 2008R2中通过数据库复制,把A表的数据复制到B表 经常在论坛中看到有人问数据同步的技术,如果只是同步少量的表,那么可以考虑使 ...
- MySQL数据库的高可用性分析
MySQL数据库是目前开源应用最大的关系型数据库,有海量的应用将数据存储在MySQL数据库中.存储数据的安全性和可靠性是生产数据库的关注重点.本文分析了目前采用较多的保障MySQL可用性方案. MyS ...
- 腾讯云数据库团队:MySQL数据库的高可用性分析
作者介绍:易固武,腾讯高级工程师,参与腾讯账号安全建设,腾讯数据仓库(TDW)优化改造,腾讯云数据库等项目,对大规模分布式存储和计算系统有浓厚的兴趣和经历 MySQL数据库是目前开源应用最大的关系型数 ...
- MySQL 数据库的高可用性分析
MySQL数据库是目前开源应用最大的关系型数据库,有海量的应用将数据存储在MySQL数据库中.存储数据的安全性和可靠性是生产数据库的关注重点.本文分析了目前采用较多的保障MySQL可用性方案. MyS ...
- SQL Server中的高可用性(1)----高可用性概览
自从SQL Server 2005以来,微软已经提供了多种高可用性技术来减少宕机时间和增加对业务数据的保护,而随着SQL Server 2008,SQL Server 2008 R2,SQL ...
- pgpool中定义的数据库节点及pgpool支持的复制模式
/* * The first DB node id appears in pgpool.conf or the first "live" DB * node otherwise. ...
- mysql 分片
MySQL Fabric(分片) 是一个用于管理 MySQL 服务器群的可扩展框架.该框架实现了两个特性 — 高可用性 (HA ) 以及使用数据分片的横向扩展.这两个特性既可以单独使用,也可以结合使 ...
- SQL Server 2005高可用性模式下创建数据库镜像
SQL Server 2005高可用性模式下创建数据库镜像 高可用性模式下创建数据库镜像 第一步: --创建镜像用数据库-在主服务器上操作 create database db_mirror on ...
随机推荐
- C++代码雨
闲逛的时候发现了一个很好玩的程序 摘自:https://blog.csdn.net/u012837895/article/details/20849967#comments 效果如下 #include ...
- ValueError: Unknown label type: 'continuous'
说明:SVM训练的标签列必须为整型数值,不能为float.y = np.array(y, dtype=int)或y.astype('int')
- P5530 [BOI 2002]双调路径
题意描述 [BOI 2002]双调路径 题意描述的确实不是很清楚(出题人惜字如金). 给定一张有 \(n\) 个点,\(m\) 条边的无向图,每条边有两个权值,分别表示经过这个点的代价和时间. 同时给 ...
- CF1324B
感觉 \(O(tn^2)\) 不是正解,于是弱弱的发了一波 \(O(tn)\) . 题意描述 你谷还没有人翻译,这里就简单介绍一下. 给你一个长为 \(n\) 的序列,如果它的一个长度至少为 \(3\ ...
- python开发基础(二)常用数据类型调用方法
1 数字: int 2 3 int : 转换,将字符串转化成数字 4 num1 = '123' 5 num2 = int (a) 6 numadd = num2 +1000 7 print(num2) ...
- phpstorm XDebug 调试
最近要实现php功能,要提供个接口提供访问,但是我就是个菜鸡,网上找了一堆,所以来提供踩坑心得了 参考文档: https://blog.csdn.net/yinhangbbbbb/article/de ...
- 【杂谈】JS相关的线程模型整理
1.JS是单线程吗? 是的,到目前为止,JS语言没有多线程的语法,它的执行引擎只支持单线程,也就是一个JavaScript进程内只有一个线程. 2.事件循环什么? 事件循环就是执行线程不断的从队列中取 ...
- 解决 cannot resolve 依赖包的问题
在maven import的时候 报这样的错误 之前也经常碰到这样的错误,通过reimport.清缓存等方法都可以解决.但这次试了好多次都还是这样,查看maven后发现我pom文件里也没写错. 最后是 ...
- Spider_知识目录_基础
知识目录 静态网页抓取 Spider_基础总结1_Request(get/post__url传参_headers_timeout)+Reponse Spider_基础总结2_Requests异常 Sp ...
- 第三方库文件Joi对数据进行验证的方法以及解决Joi.validate is not a function的问题
Joi:javaScript对象的规则描述语言和验证器 1.npm install joi@14.3.1 2.建立joi.js文件 3.导入第三方包joi const Joi = require('j ...