一、Pgpool-II配置
1.1 PostgreSQL相关配置
本例Postgresql安装在/usr/local/pgsql16目录,Pgpool-II安装在/home/postgres/pgpool目录。
1.在PostgreSQL主节点(db01)上设置流复制
# 根据规划,创建归档日志目录su- postgres mkdir /data/pgsql16/archive # 在主节点初始化数据库(如果你已经初始化了数据库,可跳过此步骤)# 以postgres用户身份执行/usr/local/pgsql16/bin/initdb -D /home/pgsql16/data -E utf8 -W# 修改/home/pgsql16/data/postgresql.conf文件listen_addresses ='*'archive_mode = on archive_command ='cp "%p" "/home/pgsql16/archive/%f"'max_wal_senders =10max_replication_slots =10wal_level = replica hot_standby = on wal_log_hints = on
在主节点启动后,我们将使用Pgpool-II的在线恢复(Online Recovery)功能设置从节点。
2.创建相关用户
基于安全考虑,创建repl用户用于流复制,pgpool用户用于流复制延迟检查及Pgpool健康检查。
用户名 |
密码 |
描述 |
repl | repl | PostgreSQL复制用户 |
pgpool | pgpool | Pgpool-II健康检查 (health_check_use)及复制延迟检查 (sr_check_user) 用户 |
postgres | postgres | 运行在线恢复的用户 |
[db01]# psql -U postgres -p 5432postgres=# SET password_encryption = 'scram-sha-256';postgres=# CREATE ROLE pgpool WITH LOGIN;postgres=# CREATE ROLE repl WITH REPLICATION LOGIN;postgres=# \password pgpoolpostgres=# \password repl
如果想在show pool_nodes的结果里显示"replication_state"和"replication_sync_state"列,pgpool用户需要有数据库的超级用户权限或者添加到pg_monitor组(>=Pgpool-II 4.1):
GRANT pg_monitor TO pgpool;
修改/data/pgsql16/data/pg_hba.conf,允许子网内其它节点访问主节点并开启scram-sha-256认证
host all all 192.168.0.0/24 scram-sha-256 host replication all 192.168.0.0/24 scram-sha-256
3.设置主从节点postgres用户ssh免密登录
如果要使用自动故障转移和在线恢复功能,需要设置主从节点间postgres用户免密登录,为方便配置时在各节点间复制文件,可先给postgres用户设置一个密码,配置完成后再删除密码。
# 在root用户下执行# passwd postgres
在每个节点上执行如下命令创建ssh密钥,并将公钥分发到各个节点,这里假设创建的密钥名为id_rsa_pgpool。
[all servers]# mkdir ~/.ssh[all servers]# chmod 700 ~/.ssh[all servers]# cd ~/.ssh[all servers]# ssh-keygen -t rsa -f id_rsa_pgpool[all servers]# ssh-copy-id -i id_rsa_pgpool.pub postgres@server1[all servers]# ssh-copy-id -i id_rsa_pgpool.pub postgres@server2[all servers]# ssh-copy-id -i id_rsa_pgpool.pub postgres@server3[all servers]# su - postgres[all servers]$ mkdir ~/.ssh [all servers]$ chmod700 ~/.ssh [all servers]$ cd ~/.ssh [all servers]$ ssh-keygen-t rsa -f id_rsa_pgpool [all servers]$ ssh-copy-id-i id_rsa_pgpool.pub postgres@server1 [all servers]$ ssh-copy-id-i id_rsa_pgpool.pub postgres@server2 [all servers]$ ssh-copy-id-i id_rsa_pgpool.pub postgres@server3 ......
密钥创建分发完成后,执行ssh postgres@db0x -i ~/.ssh/id_rsa_pgpool,检查是否不需要输入密码就可以登录成功。如果无法使用公钥登录,需要检查相关配置:
- 检查/etc/ssh/sshd_config文件PubkeyAuthentication选项是否为 yes
- 如果运行ssh-copy-id时无法通过密码登录其他节点,可在/etc/ssh/sshd_config文件中临时设置PasswordAuthentication yes
- 如果启用了selinux,ssh免密登录也可能会失败,可做如下操作:
[all servers]# su - postgres[all servers]$ restorecon-Rv ~/.ssh
确保几个节点相互之间均可以通过ssh免密码登录后,继续配置。
4.建立PostgreSQL密码文件
在流复制跟在线recovery时需要repl用户密码,执行pg_rewind时需要postgres超级用户的密码,因此需要在postgres的家目录下创建.pgpass密码文件(重要!!!):
[all servers]# su - postgres[all servers]$ vi$HOME/.pgpass server1:5432:replication:repl:<repl user password> server2:5432:replication:repl:<repl user password> server3:5432:replication:repl:<repl user password> server1:5432:postgres:postgres:<postgres user password> server2:5432:postgres:postgres:<postgres user password> server3:5432:postgres:postgres:<postgres user password> [all servers]$ chmod600$HOME/.pgpass
创建完成后用scp复制到其他节点的postgres家目录下。
5.防火墙设置
如果启用了防火墙,需要设置防火墙允许相应端口:
[all servers]# firewall-cmd --permanent --zone=public --add-service=postgresql[all servers]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp --add-port=9694/udp[all servers]# firewall-cmd --reload
6.创建节点文件pgpool_node_id
需要在每个节点机的/home/postgresql/pgpool/etc目录下创建一个节点文件pgpool_node_id用于标识节点ID,以便看门狗识别每个节点,每个节点ID不能相同。
[server1]# cat /etc/pgpool-II/pgpool_node_id0[sever2]# cat /etc/pgpool-II/pgpool_node_id1[server3]# cat /etc/pgpool-II/pgpool_node_id2
1.2 Pgpool-II配置
源码安装,配置文件在/home/postgres/pgpool/etc目录下,复制pgpool.conf.sample文件为pgpool.conf,然后修改相应选项。
1.集群模式
Pgpool-II支持多种集群模式,这里推荐使用PostgreSQL的流复制模式
backend_clustering_mode ='streaming_replication'
2.侦听地址、端口号
listen_addresses ='*'port =9999
3.流复制检查
sr_check_user ='pgpool'#密码置空,使用pool_passwd文件sr_check_password =''
4.健康检查
启用运行状况检查,以便Pgpool-II执行故障切换。此外,如果网络不稳定,即使后端运行正常,健康检查也会失败,可能会发生故障切换或退化操作。为了防止此类错误检测运行状况检查,我们将Health_check_max_reries设置为3。
health_check_period =5health_check_timeout =30health_check_user ='pgpool'#密码置空,使用pool_passwd文件health_check_password =''health_check_max_retries =3
5.PostgreSQL服务端设置
本例添加了三个节点
backend_hostname0 ='server1'#主机名或IP地址backend_port0 =5432backend_weight0 =1backend_data_directory0 ='/data/pgsql16/data'backend_flag0 ='ALLOW_TO_FAILOVER'backend_hostname1 ='server2'backend_port1 =5432backend_weight1 =1backend_data_directory1 ='/data/pgsql16/data'backend_flag1 ='ALLOW_TO_FAILOVER'backend_hostname2 ='server3'backend_port2 =5432backend_weight2 =1backend_data_directory2 ='/data/pgsql16/data'backend_flag2 ='ALLOW_TO_FAILOVER'
如果想在show pool_nodes的结果里显示"replication_state" and "replication_sync_state"列,需要设置backend_application_name参数。这里我们设置成后端主机名。(>=Pgpool-II 4.1)
... backend_application_name0 ='server1'... backend_application_name1 ='server2'... backend_application_name2 ='server3'
6.故障转移配置
在failover_command参数中指定故障转移后要执行的failover.sh脚本。如果我们使用3台PostgreSQL服务器,则需要指定flow_primary_command用于在主节点故障转移后进行后续处理。如果有两台PostgreSQL服务器,则不需要设置flow_primary_command。
failover_command ='/home/postgres/pgpool/etc/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'follow_primary_command ='/home/postgres/pgpool/etc/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'
/home/postgres/pgpool/etc目录下有相关脚本的的示例文件,需要根据自身情况做相应的修改。修改完成后scp到其他节点相同目录下。
[all servers]# cd /home/postgres/pgpool/etc[all servers]# cp -p failover.sh.sample failover.sh[all servers]# cp -p follow_primary.sh.sample follow_primary.sh[all servers]# chown postgres:postgres failover.sh follow_primary.sh# 这两个脚本文件主要修改PG_HOME这一项,改为自己的PostgreSQL安装目录
follow_primary_command所设置的脚本follow_primary.sh脚本还需要执行pcp命令,还需要做pcp密码验证,因些还要修改follow_primary.sh的PCP_USER参数,这里我们使用pgpool用户。
# cat /home/postgres/pgpool/etc/follow_primary.sh... PCP_USER=pgpool ...
使用pg_md5程序加密pgpol密码并保存到/home/postgres/pgpool/etc/pcp.conf文件中:
[all servers]# echo 'pgpool:'`pg_md5 pgpool密码` >> /etc/pgpool-II/pcp.conf
为了让follow_primary.sh脚本执行pcp命令时无需输入密码,需要在postgres用户的家目录下生成.pcppass文件。
[all servers]# su - postgres[all servers]$ echo'localhost:9898:pgpool:<pgpool用户密码>' > ~/.pcppass [all servers]$ chmod600 ~/.pcppass
7.在线recovery配置
在线recovery需要超级用户权限,因此需要以postgres用户的身份运行,需要执行recovery_1st_stage_command和recovery_2nd_stage_command参数指定的脚本,配置如下:
recovery_user ='postgres'recovery_password =''recovery_1st_stage_command ='recovery_1st_stage'recovery_2nd_stage_command ='pgpool_remote_start'
这两个脚本在/home/postgres/pgpool/etc目录下也有相应的用例,根据自己的场景修改相关参数,主要修改PG_HOME参数。并将修改好的脚本文件复制到PG_HOME目录,赋予可执行权限。
[server1]# cp -p /home/postgres/pgpool/etc/recovery_1st_stage.sample /data/pgsql16/data/recovery_1st_stage[server1]# cp -p /home/postgres/pgpool/etc/pgpool_remote_start.sample /data/pgsql16/data/pgpool_remote_start[server1]# chown postgres:postgres /home/pgsql16/data/{recovery_1st_stage,pgpool_remote_start}[server1]# chmod +x /home/pgsql16/data/{recovery_1st_stage,pgpool_remote_start}
在线recovery需要用到pgpool_recovery扩展提供的pgpool_recovery
, pgpool_remote_start
, pgpool_switch_xlog
函数,因此需要在主节点的template1数据库模板上创建pgpool_recovery扩展
[server1]# su - postgres[server1]$ psql template1 -c"CREATE EXTENSION pgpool_recovery"
8.客户端认证配置
出于安全原因,客户端访问pgpool里也需要密码认证,因些需要配置pgpool的密码认证,类似于PostgreSQL的pg_hba.conf,pgpool的配置文件保存在/home/postgres/pgpool/etc目录下,文件名为pool_hba.conf,我们使用scram-sha-256算法。
enable_pool_hba = on pool_passwd ='pool_passwd'
pool_hba.conf
host all pgpool 192.168.0.0/24 scram-sha-256 host all postgres 192.168.0.0/24 scram-sha-256
此外还需要为所有需要通过Pgpool访问PostgreSQL数据库的用户创建Pgpool的密码文件,密码文件位于/home/postgres/pgpool/etc目录下,缺省文件名为:pool_passwd。密码使用AES算法加密,需要先生成.pgpoolkey文件,文件中保存加密用的密钥。
[all servers]# su - postgres[all servers]$ echo'some string' > ~/.pgpoolkey [all servers]$ chmod600 ~/.pgpoolkey
生成key文件后,执行pg_enc -m -k /path/to/.pgpoolkey -u username -p生成用户的密码。
[all servers]# su - postgres[all servers]$ pg_enc-m-k ~/.pgpoolkey -u pgpool -pdb password: [pgpool user's password][all servers]$ pg_enc -m -k ~/.pgpoolkey -u postgres -pdb password: [postgres user's password] # cat /home/postgres/pgpool/etc/pool_passwdpgpool:AESheq2ZMZjynddMWk5sKP/Rw==postgres:AESHs/pWL5rtXy2IwuzroHfqg==
9.看门狗配置
# 看门狗相关use_watchdog = on # 节点1hostname0 ='server1'wd_port0 =9000pgpool_port0 =9999# 节点2hostname1 ='server2'wd_port1 =9000pgpool_port1 =9999# 节点3hostname2 ='server3'wd_port2 =9000pgpool_port2 =9999delegate_ip ='192.168.0.5'#浮动IPif_cmd_path ='/usr/sbin'if_up_cmd ='/usr/bin/sudo /usr/sbin/ip addr add $_IP_$/32 dev eth0 label eth0:0'if_down_cmd ='/usr/bin/sudo /usr/sbin/ip addr del $_IP_$/32 dev eth0'arping_path ='/usr/sbin'arping_cmd ='/usr/bin/sudo /usr/bin/arping -U $_IP_$ -w 1 -I eth0'ping_path ='/usr/bin'wd_escalation_command ='/home/postgres/pgpool/etc/escalation.sh'heartbeat_hostname0 ='server1'heartbeat_port0 =9694heartbeat_device0 =''heartbeat_hostname1 ='server2'heartbeat_port1 =9694heartbeat_device1 =''heartbeat_hostname2 ='server3'heartbeat_port2 =9694heartbeat_device2 =''wd_heartbeat_keepalive =2wd_heartbeat_deadtime =30
看门狗在做浮动IP切换、执行arping检查其他节点是否存活时需要以root权限执行,需要为postgres用户设置相应的权限,使用visudo编辑权限,加上如下内容:
postgres ALL=NOPASSWD: /usr/sbin/ip postgres ALL=NOPASSWD: /usr/bin/arping
wd_escalation_command指定浮动IP切换脚本,/home/postgres/pgpool/etc目录下有相应用例escalation.sh.sample,根据自身情况修改:
[all servers]# cd /home/postgres/pgpool/etc[all servers]# cp -p escalation.sh.sample escalation.sh[all servers]# chown postgres:postgres escalation.sh[all servers]# chmod +x escalation.sh[all servers]# vi escalation.sh... PGPOOLS=(server1 server2 server3) VIP=192.168.137.5 # 需要绑定的网卡名可通过ifconfig -a查看DEVICE=eth0
10.日志配置
logging_collector = on log_directory ='/home/postgres/pgpool/logs'log_filename ='pgpool-%Y-%m-%d_%H%M%S.log'log_truncate_on_rotation = on log_rotation_size = 100MB pid_file_name ='/home/postgres/pgpool/logs/pgpool.pid'logdir ='/tmp'
附:一个完整的配置文件例子
backend_clustering_mode ='streaming_replication'listen_addresses ='*'port =9999unix_socket_directories ='/tmp'pcp_listen_addresses ='*'pcp_port =9898pcp_socket_dir ='/tmp'# masterbackend_hostname0 ='server1'#主机名或IP地址backend_port0 =5432backend_weight0 =1backend_data_directory0 ='/data/pgsql16/data'backend_flag0 ='ALLOW_TO_FAILOVER'backend_application_name0 ='server0'# standby-1backend_hostname1 ='server2'backend_port1 =5432backend_weight1 =1backend_data_directory1 ='/data/pgsql16/data'backend_flag1 ='ALLOW_TO_FAILOVER'backend_application_name1 ='server1'# standby-2backend_hostname2 ='server3'backend_port2 =5432backend_weight2 =1backend_data_directory2 ='/data/pgsql16/data'backend_flag2 ='ALLOW_TO_FAILOVER'backend_application_name2 ='server2'enable_pool_hba = on pool_passwd ='pool_passwd'process_management_mode = dynamic num_init_children =32min_spare_children =5max_spare_children =10max_pool =4# 日志相关logging_collector = on log_directory ='/home/postgres/pgpool/logs'log_filename ='pgpool-%Y-%m-%d_%H%M%S.log'log_truncate_on_rotation = on log_rotation_size = 100MB pid_file_name ='/home/postgres/pgpool/logs/pgpool.pid'logdir ='/tmp'connection_cache = on #连接池开启load_balance_mode = on #负载均衡开启disable_load_balance_on_write ='transaction'#应用有事务时一定要设置# 健康检查相关sr_check_user ='pgpool'sr_check_password =''health_check_period =5health_check_timeout =30health_check_user ='pgpool'health_check_password =''health_check_max_retries =3# failover、recovery相关failover_command ='/home/postgres/pgpool/etc/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'follow_primary_command ='/home/postgres/pgpool/etc/follow_primary.sh %d %h %p %D %m %H %M %P %r %R'recovery_user ='postgres'recovery_password =''recovery_1st_stage_command ='recovery_1st_stage'recovery_2nd_stage_command ='pgpool_remote_start'# 看门狗相关use_watchdog = on # 节点1hostname0 ='server1'wd_port0 =9000pgpool_port0 =9999# 节点2hostname1 ='server2'wd_port1 =9000pgpool_port1 =9999# 节点3hostname2 ='server3'wd_port2 =9000pgpool_port2 =9999delegate_ip ='192.168.0.5'#浮动IPif_cmd_path ='/usr/sbin'if_up_cmd ='/usr/bin/sudo /usr/sbin/ip addr add $_IP_$/32 dev eth0 label eth0:0'if_down_cmd ='/usr/bin/sudo /usr/sbin/ip addr del $_IP_$/32 dev eth0'arping_path ='/usr/sbin'arping_cmd ='/usr/bin/sudo /usr/bin/arping -U $_IP_$ -w 1 -I eth0'ping_path ='/usr/bin'wd_escalation_command ='/home/postgres/pgpool/etc/escalation.sh'heartbeat_hostname0 ='server1'heartbeat_port0 =9694heartbeat_device0 =''heartbeat_hostname1 ='server2'heartbeat_port1 =9694heartbeat_device1 =''heartbeat_hostname2 ='server3'heartbeat_port2 =9694heartbeat_device2 =''wd_heartbeat_keepalive =2wd_heartbeat_deadtime =30
配置完成后将pgpool.conf复制到其他节点(server2、server3)。各节点的pgpool.conf内容均相同,无需修改。
[server1]$ scp-p /home/postgres/pgpool/etc/pgpool.conf postgres@server2://home/postgres/pgpool/etc/. [server1]$ scp-p /home/postgres/pgpool/etc/pgpool.conf postgres@server3://home/postgres/pgpool/etc/.