文档结构:

由于博主之前是Oracle dba,oracle 高可用一般是rac,以及搭建ADG,一个是基于实例的高可用,一个是基于数据的容灾,甚至也有rac+adg的方式。Postgres有同步和异步两种同步方式,我发现,mysql,oracle,postgresql 这两种同步模式原理都是一个德行,可能都是绕不开关系型数据库吧。

异步方式主库上的事务不会等待备库接受日志流发出确认信息后主库才向客户端返回成功,同步方式事务会主库等待至少一个备库接受日志流发出确认信息后便返回成功;很明显,异步时间会有延迟,同步会增加相应时间,但是保证了数据的一致性,在资源允许的情况下,可以一主多从且采取一个备库同步,多个备库异步方式。

除了pgpool异步高可用,还可以采用keepalived方式,本次就简单实验pgpool异步方式。

什么是pgpool-Ⅱ

Pgpool-II是一个在PostgreSQL服务器和PostgreSQL数据库客户端之间工作的中间件。它是根据BSD许可证授权的。它提供以下功能。

连接池

Pgpool-II保存与PostgreSQL服务器的连接,并在具有相同属性(即用户名,数据库,协议版本)的新连接进入时重用它们。它减少了连接开销,并提高了系统的整体吞吐量。

复制

Pgpool-II可以管理多个PostgreSQL服务器。使用复制功能可以在2个或更多物理磁盘上创建实时备份,以便在磁盘发生故障时服务可以继续运行而不会停止服务器。

负载均衡

如果复制了数据库,则在任何服务器上执行SELECT查询都将返回相同的结果。Pgpool-II利用复制功能,通过在多个服务器之间分配SELECT查询来减少每个PostgreSQL服务器的负载,从而提高系统的整体吞吐量。充其量,性能与PostgreSQL服务器的数量成比例地提高。在许多用户同时执行许多查询的情况下,负载平衡最有效。

限制超出连接

PostgreSQL的最大并发连接数有限制,连接在这么多连接后被拒绝。但是,设置最大连接数会增加资源消耗并影响系统性能。pgpool-II对最大连接数也有限制,但额外连接将排队,而不是立即返回错误。

看家狗

Watchdog可以协调多个Pgpool-II,创建一个强大的集群系统,避免单点故障或脑裂。看门狗可以对其他pgpool-II节点执行生命检查,以检测Pgpoll-II的故障。如果活动Pgpool-II发生故障,则可以将备用Pgpool-II提升为活动状态,并接管虚拟IP。

在内存查询缓存中

在内存中查询缓存允许保存一对SELECT语句及其结果。如果有相同的SELECT,Pgpool-II将从缓存中返回值。由于不涉及SQL解析或访问PostgreSQL,因此在内存缓存中使用速度非常快。另一方面,在某些情况下,它可能比正常路径慢,因为它增加了存储缓存数据的一些开销。

Pgpool-II讲PostgreSQL的后端和前端协议,并在后端和前端之间传递消息。因此,数据库应用程序(前端)认为Pgpool-II是实际的PostgreSQL服务器,服务器(后端)将Pgpool-II视为其客户端之一。因为Pgpool-II对服务器和客户端都是透明的,所以现有的数据库应用程序可以与Pgpool-II一起使用。Pgpool-II讲述PostgreSQL的后端和前端协议,并在它们之间传递连接。因此,数据库应用程序(前端)认为Pgpool-II是实际的PostgreSQL服务器,服务器(后端)将Pgpool-II视为其客户端之一。因为Pgpool-II对服务器和客户端都是透明的,所以现有的数据库应用程序可以与Pgpool-II一起使用,几乎不需要更改其源码。

以下测试主要来自谭峰(francs)老师的《postgres 实战》

一.Pgpool-Ⅱ的安装

主机名

说明

IP地址

端口

版本

10pg1

主库

192.168.10.41

5432

Postgres10.8

pgpool主

5555

VIP

192.168.10.61

10pg2

备库

192.168.10.51

5433

Postgres10.8

pgpool备

5555

其中,应用连接vip,防火墙建议关闭,同时,生产上肯定不是postgres这库了,肯定时业务库了,这个按照实际情况配置。

1.   下载地址

https://www.pgpool.net/mediawiki/index.php/Downloads

我是采用rpm的最新版本4.0.6。

2.   部署(主备)

yum -y install libmemcached

export PATH=$PATH:/usr/local/pgsql/bin/

mkdir /pgpool

./configure --prefix=/pgpool --with-pgsql=/pgpool/

make

make install

安装生成的配置文件在/pgpool/ 目录下。

注意如果提示:

configure: error: libpq is not installed or libpq is old

如果配置了环境变量(PATH,PGHOME,PGDATA)还是出现以上错误,建议使用

./configure --prefix=/pgpool

make

make install

并把pgpool配置到环境变量中(root,postgres用户下)

1.   配置pgpool主备服务器互信(非root设置)

我用postgres 执行故障转移脚本,所以进行互信设置把

vi /etc/hosts

192.168.10.41  10pg1

192.168.10.52  10pg2

ssh-keygen

ssh-copy-id postgres@10pg2

同理在备库上执行

ssh-keygen

ssh-copy-id postgres@10pg1

测试:

ssh postgres@10pg2

ssh postgres@10pg1

1.   配置pool_hba.conf连接配置文件

Postgres针对连接策略需要配置pg_hba.conf文件,而pgpool连接中由于应用程序是线连接pgpool,然后通过pgpool再连接到后端数据库,因此也需要在pgpool层面进行连接配置。

Pgpool的配置跟pg_hba.conf一样的。

cd /pgpool/etc/

cp pool_hba.conf.sample pool_hba.conf

vi pool_hba.conf

加上192.168.10.0 这个网段的ip 都可以的访问

host    all         all         0.0.0.0/0      md5

1.   配置密码配置文件

默认文件是不存在的,生成pool_passwd配置文件

pg_md5 命令生成

pg_md5 -u postgres -m 密码

或者 手工建一个文件,怕密码泄露

select rolpassword from pg_authid where rolname='postgres';

vi pool_passwd

postgres:md53175bce1d3201d16594cebf9d7eb3f9d

rep:md5df2c887bcb2c49b903aa33bdbc5c2984

1.   配置pgpool.conf配置文件

cp /pgpool/etc/pgpool.conf.sample-stream /pgpool/etc/pgpool.conf

vi /pgpool/etc/pgpool.conf

需要修改的(由于参数太多直接写结果吧):

主库参数配置:

 

port = 5555

listen_addresses = '*'          #表示监听所有地址连接(跟postgres参数一样的意思)

backend_hostname0 = '192.168.10.41'   #配置节点0的hostname

backend_port0 = 5432          #主库端口

backend_weight0 = 1           #没有开启模式参数配不配之都可以

backend_data_directory0 = '/pgsql/pg_data'  #节点0数据目录

backend_flag0 = 'ALLOW_TO_FAILOVER'   #主库是否允许故障转移

backend_hostname1 = '192.168.10.51'

backend_port1 = 5433

backend_weight1 = 1

backend_data_directory1 = '/pgsql/pg_data'

backend_flag1 = 'ALLOW_TO_FAILOVER'

enable_pool_hba = on  #表示启用pool_hba.conf

pool_passwd = 'pool_passwd'   #设置MD5认证的密码文件

log_destination = 'syslog'  #日志

pid_file_name = '/pgpool/pgpool.pid'

load_balance_mode = off  #关闭负载均衡(如果开启,select语句会在备库执行)

master_slave_mode = on

master_slave_sub_mode = 'stream'

sr_check_period = 10  #流复制检查10s

sr_check_user = 'rep' #我同步采用的rep 用户

sr_check_password = 'rep'

sr_check_database = 'postgres'  #流复制检查连接的数据库

delay_threshold = 10000000 这个是备库延迟wal/xlog日志大于10000000字节,将不会select语句分发到备库

health_check_period= 5

health_check_timeout = 20

health_check_user = 'rep'

health_check_password = 'rep'

health_check_database = 'postgres'

health_check_max_retries = 3

health_check_retry_delay = 3

failover_command = '/pgpool/etc/failover_stream.sh %d %P %H %R'

use_watchdog = on #启用watchdog

wd_hostname = '192.168.10.41'

wd_port = 9000

wd_priority = 1 ##表示watchdog的优先级,级别越高则被选为主节点,一主一从设置一样

delegate_IP = '192.168.10.61' #设置的VIP

if_cmd_path = '/sbin'

if_up_cmd = 'ip addr add $_IP_$/24 dev eth0 label eth0:0' 我的环境是eth0

if_down_cmd = 'ip addr del $_IP_$/24 dev eth0'

heartbeat_destination0 = '192.168.10.51'

heartbeat_destination_port0 = 9694

heartbeat_device0 = 'eth0'

wd_life_point = 3 #当探测pgpool节点失败后设置重试次数

wd_lifecheck_query = 'SELECT 1'

wd_lifecheck_dbname = 'postgres'

wd_lifecheck_user = 'rep'

wd_lifecheck_password = 'rep'

other_pgpool_hostname0 = '10pg2'  #设置远程pgpool节点主机

other_pgpool_port0 = 5555  #设置远程pgpool端口号

other_wd_port0 = 9000     #设置远程pgpool节点watchdog端口号

从库参数配置:

 

port = 5555

listen_addresses = '*'          #表示监听所有地址连接(跟postgres参数一样的意思)

backend_hostname0 = '192.168.10.41'   #配置节点0的hostname

backend_port0 = 5432        #端口

backend_weight0 = 1           #没有开启模式参数配不配之都可以

backend_data_directory0 = '/pgsql/data'  #节点0数据目录

backend_flag0 = 'ALLOW_TO_FAILOVER'   #节点0是否允许故障转移

backend_hostname1 = '192.168.10.51'     #节点1的主机名

backend_port1 = 5433      #节点1的端口

backend_weight1 = 1           #没有开启模式参数配不配之都可以

backend_data_directory1 = '/pgsql/data'  #节点1数据目录

backend_flag1= 'ALLOW_TO_FAILOVER'   #节点1是否允许故障转移

enable_pool_hba = on  #表示启用pool_hba.conf

pool_passwd = 'pool_passwd'   #设置MD5认证的密码文件

log_destination = 'syslog'  #日志

pid_file_name = '/pgpool/pgpool.pid'

load_balance_mode = off  #关闭负载均衡(如果开启,select语句会在备库执行)

master_slave_mode = on

master_slave_sub_mode = 'stream'

sr_check_period = 10  #流复制检查10s

sr_check_user = 'rep' #我同步采用的rep 用户

sr_check_password = 'rep'

sr_check_database = 'postgres'  #流复制检查连接的数据库

delay_threshold = 10000000 这个是备库延迟wal/xlog日志大于10000000字节,将不会select语句分发到备库

health_check_period= 5

health_check_timeout = 20

health_check_user = 'rep'

health_check_password = 'rep'

health_check_database = 'postgres'

health_check_max_retries = 3

health_check_retry_delay = 3

failover_command = '/pgpool/etc/failover_stream.sh'

use_watchdog = on #启用watchdog

wd_hostname = '10pg2'

wd_port = 9000

wd_priority = 1  ##表示watchdog的优先级,级别越高则被选为主节点,一主一从设置一样

delegate_IP = '192.168.10.61' #设置的VIP

if_cmd_path = '/sbin'

if_up_cmd = 'ip addr add $_IP_$/24 dev eth0 label eth0:0' 我的环境是eth0

if_down_cmd = 'ip addr del $_IP_$/24 dev eth0'

heartbeat_destination0 = '192.168.10.41'

heartbeat_destination_port0 = 9694

heartbeat_device0 = 'eth0'

wd_life_point = 3  #当探测pgpool节点失败后设置重试次数

wd_lifecheck_query = 'SELECT 1'

wd_lifecheck_dbname = 'postgres'

wd_lifecheck_user = 'rep'

wd_lifecheck_password = 'rep'

other_pgpool_hostname0 = '192.168.10.41'  #设置远程pgpool节点主机

other_pgpool_port0 = 5555  #设置远程pgpool端口号

other_wd_port0 = 9000     #设置远程pgpool节点watchdog端口号

1.  配置failover_stream.sh脚本

cat /pgpool/etc/failover_stream.sh

#! /bin/bash

# Executes this command after master failover

# Special values:

#   %d = node id

#   %h = host name

#! /bin/bash

# Executes this command after master failover

# Special values:

#   %d = node id

#   %h = host name

#   %p = port number

#   %D = database cluster path

#   %m = new master node id

#   %H = hostname of the new master node

#   %M = old master node id

#   %P = old primary node id

#   %r = new master port number

#   %R = new master database cluster path

#   %% = '%' character

falling_node=$1

old_primary=$2

new_primary=$3

pgdata=$4

pghome=/usr/local/pgsql/

log=/pgpool/failover.log

date >> $log

#输出变量到日志,方便此脚本出现异常时调试

echo "falling_node=$falling_node" >> $log

echo "old_primary=$old_primary" >> $log

echo "new_primary=$new_primary" >> $log

echo "pgdata=$pgdata" >> $log

##如果故障的数据库为主库并且执行脚本的操作系统用户为root

if [ $falling_node = $old_primary ] && [ $UID -eq 0 ];then

if [ -f $pgdata/recovery.conf ];then

su  postgres -c "$pghome/bin/pg_ctl promote -D $pgdata"

echo "Local promote" >> $log

else

su postgres -c "ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata"

echo "Remote promote" >> $log

fi

fi

exit 0;

脚本主要是通过有没有recovery.conf文件来判断为主备,会调用ip addr添加或者删除IP地址,使用root维护pgpool程序会方便些。需要给root 添加环境变量:

export PGPOOL_HOME=/pgpool

export PATH=$PATH:$HOME/bin:/pgpool/bin/:$PGPOOL_HOME/bin

在主库上启动pgpool(root用户)

pgpool

查看主库启动的vip

查看日志:

查看p'g'pool参数的使用:

个人感觉跟pg_ctl 类似,尤其是加载参数:

pgpool reload

或者关闭pgpool -m fast stop

Shutdown modes are:

smart       quit after all clients have disconnected

fast        quit directly, with proper shutdown

immediate   the same mode as fast

关闭是这三种状态

日志查看是:

tail -100f /var/log/messages

后面启动从库pgpool:

主库日志:

从库日志:

如果从库起不来 或者报错,那肯定是参数设置错了,根据日志去修改参数,值得注意的是,这里面参数很多是本库的,也有很多是远端库的,一定要配置对。

通过vip 查看pgpool 状态:

psql -h 192.168.10.61 -p5555 postgres

show pool_nodes;

悲剧的是主库居然pgpool 状态为down,也就是日志说的node 0 0,正常应该node 0 2;

反复检查参数配置没有错,于是执行(一般主备库重启后,状态异常可以执行以下语句):

pcp_attach_node -h 192.168.10.61 -U pgpool 0

注意,0为节点1,如果是备库有问题,就是pcp_attach_node -h 192.168.10.61 -U pgpool 1,然后就正常了

如下图:

如果主备库关闭过,也需要重新连接pgpool

pcp_attach_node -h 192.168.10.61 -U pgpool 0或者1

8.  PCP管理接口配置

pgpool提供一个用于管理pgpool 的系统层命令工具,pcp用户属于pgpool 层面,和数据库中的用户没有关系,例如查看pgpool 节点信息,增加pgpool 节点,断开pgpool 节点等。

例如,我设置PCP层面密码为pgpool

[root@10pg1 ~]# pg_md5 pgpool

ba777e4c2f15c11ea8ac3be7e0440aa0

cd /pgpool/etc/

cp pcp.conf.sample pcp.conf

添加到

vi pcp.conf

二.高可用测试

1.  查看pgpool状态

pcp命令查看pcp节点,watchdog信息等。

pcp_node_info --verbose -h 192.168.10.61 -U pgpool 0

Status 字段值意思:

0为初始化

1为以启动没有连接

2为以启动有链接

3节点关闭

查看watchdog集群信息:

pcp_watchdog_info --verbose -h 192.168.10.61 -U pgpool

2.  高可用测试

a. 关闭pgpool程序

停掉主节点的pgpool 程序

pgpool -m stop fast

查看主库IP:

主库已经删除了VIP 61

查看系统日志:

主库:

备库:

备库接管了VIP

登录进去查看:

psql -h 192.168.10.61 -p5555 postgres postgres

虽然备库接管了VIP,但是没有发生failover切换,单独的pgpool程序故障并不会发生数据库主备切换(主机数据库宕机除外,待会测试)。

b. 只关闭postgres 流复制主库

把主库上的pgpool开启,主库服务器没有接管VIP,重启一下备库pgpool,让主库接管vip,再启动备库pgpool做关闭数据库测试。

pg_ctl stop -D /pgsql/pg_data  -m fast

查看备库日志:

查看VIP

可以查看的是VIP 虽然仍然再10pg1上,但是其实现在连接的时新主库:

测试:

已经发生failover.

查看新主库:

Failover 成功。查看关闭的库failover的日志:

这个日志时再原主库上生成的failover日志

c. 关闭postgres 主库主机

重新搭建主从同步。

关闭主库主机相当于关闭数据库和pgpool了,个人猜想时vip 会飘过来,也会执行备库提升为主库。

select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;

show pool_nodes;

关闭主库服务器。

经过几秒钟VIP漂移过来了,而且备库提升为主库了。

查看新主库pgpool日志:

查看新主库发生failover的日志:

查看新主库信息

d. 总结

按照步骤来安装以及测试,如果参数没有配置错误,实验还是会比较成功。值得注意的时要配置pool_passwd和pcp密码,以及pgpool参数文件配置的时候,不要把主从参数配错了,最后更值得注意的时failover脚本,如果写错了不会发生故障转移,再重启过数据库或者pgpool程序时,如果pgpool节点状态不正常,可以利用pcp_attach_node把pgpool节点加进去,感觉备库切换主库的时候,不是立马,有点延迟,应该是跟时间参数配置有关。

Postgressql高可用(pgpool+异步流复制)的更多相关文章

  1. postgresql数据库异步流复制hot standby环境搭建

    生命不息,test不止. 最近组里面修改了几个postgresql的bug,要进行回归测试,除了前面提到的WAL的RT测试和Mirroring Controller的RT测试,还要测试下postgre ...

  2. MySQL集群架构:MHA+MySQL-PROXY+LVS实现MySQL集群架构高可用/高性能-技术流ken

    MHA简介 MHA可以自动化实现主服务器故障转移,这样就可以快速将从服务器晋级为主服务器(通常在10-30s),而不影响复制的一致性,不需要花钱买更多的新服务器,不会有性能损耗,容易安装,不必更改现有 ...

  3. Redis主从复制、多实例、高可用(三)--技术流ken

    Redis主从复制 在开始实现redis的高可用之前,首先来学习一下如何实现redis的主从复制,毕竟高可用也会依赖主从复制的技术. Redis的主从复制,可以实现一个主节点master可以有多个从节 ...

  4. 阿里云应用高可用服务 AHAS 流控降级实现 SQL 自动防护功能

    在影响系统稳定性的各种因素中,慢 SQL 是相对比较致命的,可能会导致 CPU.LOAD 异常.系统资源耗尽.线上生产环境出现慢 SQL 往往有很多原因: 硬件问题.如网络速度慢,内存不足,I/O 吞 ...

  5. postgresql 异步流复制hot standby搭建

    先说说环境,主从库版本都是9.5,主库在CentOS物理机上,从库在Ubuntu虚拟机上 一.主库上的操作: 1.添加同步访问规则: host   replication     dbuser     ...

  6. 配置管理 ACM 在高可用服务 AHAS 流控降级组件中的应用场景

    应用配置管理(Application Configuration Management,简称 ACM)是一款应用配置中心产品.基于ACM您可以在微服务.DevOps.大数据等场景下极大地减轻配置管理的 ...

  7. Postgresql 9.6 搭建 异步流复制 和 同步流复制 详细教程

    Basic Replication If you’re feeling overwhelmed, try setting up a slave to see how easy it is! We’ll ...

  8. PostgreSQL异步主从流复制搭建

    1 总体规划   Master库 Slave库 操作系统 CentOS Linux release 7.5.1804 CentOS Linux release 7.5.1804 处理器 1 1 内存 ...

  9. mysql高可用架构

    高可用   高可用(High Availabiltity) 应用提供持续不间断(可用)的服务的能力 系统高可用性的评价通常用可用率表示   造成不可用的原因 硬件故障(各种) 预期中的系统软硬件维护 ...

随机推荐

  1. Spring boot 自定义 Resolver 支持 interface 类型参数

    在编写 RestController 层的代码时,由于数据实体类定义了接口及实现类,本着面向接口编程的原则,我使用了接口作为 RestController 方法的入参. 代码大致如下(省略具体业务部分 ...

  2. 深入理解 Java 中 SPI 机制

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/vpy5DJ-hhn0iOyp747oL5A作者:姜柱 SPI(Service Provider ...

  3. 面向对象程序设计(Java) 第1周学习指导及要求

    面向对象程序设计(Java)第1周学习指导及要求 (2019.8.30-2019.9.2)   学习目标 了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具: 理解JVM.JRE与JDK等概念 ...

  4. JavaScript数组和伪数组

    伪数组和数组 记住一句话: 伪数组是一个Object,数组是Array. 对象和数组之间的关系 JavaScript的内置函数继承与 Object.prototype. 可以认为new Array() ...

  5. springcloud(四):应用配置中心config的安全设置

    springcloud应用配置中心config的安全设置 在springcloud应用开发中,为了方便在线管理我们的配置文件,通常会配一个配置中心config-server,这里托管着应用的一些配置文 ...

  6. 一键升级所有pip过期库

    import pipfrom subprocess import callfrom pip._internal.utils.misc import get_installed_distribution ...

  7. FreeSql (二十一)查询返回数据

    FreeSql 采用 ExpressionTree 优化读取速读,如果懂技术的你一定知道 .NETCore 技术下除了原生代码,最快就是 Emit 和 ExpressionTree. 项目在初期使用的 ...

  8. GO 语言学习笔记--数组切片篇

    1.对于make 数组切片,长度和容量需要理解清楚: 容量表示底层数组的大小,长度是你可以使用的大小: 容量的用处在哪?在与当你用 appen d扩展长度时,如果新的长度小于容量,不会更换底层数组,否 ...

  9. android.intent.category.BROWSABLE

    参考: http://blog.csdn.net/annkie/article/details/8349626 http://xiechengfa.iteye.com/blog/1004991 BRO ...

  10. C# DATETIME格式转换汇总 根据日期过期星期

    C# DateTime.Now.Year --2019(年) DateTime.Now.Month --9(月) DateTime.Now.Day   --19(日) DateTime.Now.Hou ...