postgresql主从部署、pgsql中间件

源码编译安装postgresql、pgpool、pgbouncer
环境:
centos 7.9
postgresql:15.6
pgpool:pgpool-II-4.5.0
pgbouncer:1.20.1
节点:
master:10.0.0.192
slave:10.0.0.193
pgpool:10.0.0.194
注意:pg10版本后,认证方式默认从md5升级到SCRAM-SHA-256,下面方式为安装pgpool统一认证方式为md5(scram-sha-256认证有些问题没有调试成功)

一、安装postgresql准备工作

1.配置节点间postgres普通用户免密登录

master执行:

ssh-keygen -t rsa
ssh-copy-id postgres@pgsql-02
ssh-copy-id postgres@pgsql-01

2.执行初始化脚本

master执行:
slave执行:

#!/bin/bash
cd /usr/local
wget http://ftp.postgresql.org/pub/source/v15.6/postgresql-15.6.tar.gz
sleep 3 
yum -y install perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel python-devel  gcc-c++ openssl-devel cmake
sleep 3
tar xvf postgresql-15.6.tar.gz
mv postgresql-15.6 /usr/local/postgresql
sleep 3
cd /usr/local/postgresql/
./configure --prefix=/usr/local/pgsql
sleep 2
make && make install
sleep 3
groupadd postgres
useradd -g postgres postgres
id postgres
cd /usr/local
mkdir pgdata
chown -R postgres.postgres pgsql
chown -R postgres.postgres pgdata
chmod 700 pgdata

cat >> /etc/profile << EOF
export PGHOME=/usr/local/pgsql
export PGDATA=/usr/local/pgdata
PATH=$HOME/bin:$PGHOME/bin:$PATH
export PATH
EOF

cat >> /home/postgres/.bash_profile << EOF
export PGHOME=/usr/local/pgsql
export PGDATA=/usr/local/pgdata
PATH=$HOME/bin:$PGHOME/bin:$PATH
export PATH
EOF

source /home/postgres/.bash_profile
source /etc/profile

二、主从部署

1.master执行

#1.初始化数据
/usr/local/pgsql/bin/initdb -D  --encoding=UTF8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8

#2.创建归档日志目录
mkdir  /usr/local/pgdata/archive

#3.设置数据库访问权限及白名单,密码认证为md5或trust无需密码认证
echo "host    replication     all             10.0.0.194/22           trust" >>  /usr/local/pgdata/pg_hba.conf
echo "host    all     all             10.0.0.192/22           trust" >>  /usr/local/pgdata/pg_hba.conf
echo "host    all             all             0.0.0.0/0               md5" >>  /usr/local/pgdata/pg_hba.conf

#4.修改配置文件
cat > /usr/local/pgdata/postgresql.conf << EOF
# basic	
listen_addresses= '*'	
port= 5432	# 端口
max_connections = 9999	# 最大连接数
superuser_reserved_connections = 10	#给超级用户预留的连接数
shared_buffers = 16GB	# 共享内存,一般设置为内存的1/4
effective_cache_size = 2GB	# 查询优化器估计的可用于缓存数据文件系统的总内存量,
max_worker_processes = 48	# 最大工作线程,和cpu核数一致
max_parallel_workers_per_gather = 4	# 单个查询在执行过程中可以使用的最大并行工作进程数,(
max_parallel_workers =24	# 整个数据库实例允许的最大并行进程数,CPU核心数的1/2
max_parallel_maintenance_workers = 6	# 维护操作期间允许的最大并行进程数,CPU核心数的1/8
work_mem = 16MB	# 设置在写入临时磁盘文件之前查询操作(例如排序或哈希表
maintenance_work_mem = 256MB	#在维护性操作(例如VACUUM、CREATE INDEX和ALTERT
timezone = 'Asia/Shanghai'	# 系统时区
hot_standby = on	# 打开热备
#_optimizer	
default_statistics_target = 500	# 默认100,ANALYZE在pg statistic中存储的信息量,
#_wal	
max_wal_size = 16GB	# 建议与shared buffers保持一致
min_wal_size = 2GB	# 建议max wal size/12.5
wal_log_hints = on	# 控制WAL日志记录的方式,建议打开
wal_level = replica	# wal日志写入级别,要使用流复制,必须使用replica或
wal_sender_timeout = 60s	# 设置WAL发送者在发送WAL数据时等待主服务器响应的超时
#_archive	# 开启归档日志
archive_command = 'gzip < %p > /usr/local/pgdata/archive/%f.gz'	
archive_mode = on	
#_log_近7天轮询	
log_destination = 'csvlog'	# 日志格式
logging_collector = on	# 日志收集器
log_directory = 'pg_log'	# 日志目录$PGDATA/pg_log
log_filename = 'postgresql-%Y-%m-%d.log'	# 日志名称格式
Log_rotation_age = 43200	# 日志保留时间单位是分钟
log_file_mode = 0600	# 日志文件的权限
log_rotation_size = 0	# 日志的最大尺寸,设置为零时将禁用基于大小创建新的日
log_truncate_on_rotation = on	# 这个参数将导致PostgreSQL截断(覆盖而不是追加)任们
Log_min_duration_statement = 0	# 如果语句运行至少指定的时间量,将导致记录每一个这种
log_duration = on	# 每一个完成的语句的持续时间被记录
log_lock_waits = on	# 控制当一个会话为获得一个锁等到超过deadlock timeo
log_statement = 'mod'	# 控制哪些 SOL 语句被记录。有效值是 none(off)、dc
log_timezone = 'Asia/Shanghai'	# 设置在服务器日志中写入的时间的时区
#_sql	
statement_timeout = 300000	# 语句执行超时时间 5分钟
idle_in_transaction_session_timeout = 300000	#事务空闲超时时间 5分钟
idle_session_timeout = 1800000	# 会话空闲超时时间 30分钟
lock_timeout = 60000	#等锁超时时间 1分钟
EOF

##切换至postergres用户
su - postgres
#5.启动数据库
/usr/local/pgsql/bin/pg_ctl start

#6.修改管理员postgres密码,创建指定用户
psql -c "ALTER ROLE postgres  WITH PASSWORD 'Aa532733691';"

#7.修改pgsql密码认证方式(pgpool前置工作)
查看数据库中用户密码协议
psql -c "show password_encryption;"
查看数据库已有用户及密码协议
psql -c "select * from pg_shadow;"
临时修改数据库中用户密码协议
psql -c "set password_encryption = 'md5';"
更改用户密码使用新协议
psql -c "ALTER ROLE postgres  WITH PASSWORD 'Aa532733691' LOGIN;"
验证数据库中用户密码协议是否更改
psql -c "select * from pg_shadow;"

#8.创建主从复制账户
psql -c "create role repl replication encrypted password 'Aa532733691';"

#9.pgpool中间件账户(pgpool前置工作)
psql -c "create role nobody login encrypted password 'Aa532733691';"
psql -c "create role pgsql login encrypted password 'Aa532733691';"
psql -c "create role pgpool login encrypted password 'Aa532733691';"
psql -c "grant postgres to nobody,pgsql,pgpool;"

2.slave执行

#1.同步主库的数据库文件,pg_basebackup是pgsql数据库物理全备服务
##切换至postergres用户
su - postgres
/usr/local/pgsql/bin/pg_basebackup -Fp --progress -D  /usr/local/pgdata -R -h 10.0.0.192 -p 5432 -U repl 

#2.创建从库专属文件standby.singal
cat > /usr/local/pgdata/standby.signal << EOF
standby_mode = on #on为从库
primary_conninfo = 'host=10.0.0.192 port=5432 user=repl password=Aa532733691' #主库信息
recovery_target_timeline = 'latest'  #流复制同步最新数据
EOF

#3.启动从数据库
/usr/local/pgsql/bin/pg_ctl start

三、查看主从数据库状态

1.master执行

su - postgres
psql -c "\x on;"
psql -c "select * from pg_stat_replication;"
#查询显示f为主库,显示t为从库
psql -c "SELECT pg_is_in_recovery();"

2.slave执行

su - postgres
psql -c "SELECT pg_is_in_recovery();"

四、配置pgpool中间件

pgpool-II 是一个数据库连接池和代理程序,可以实现读写分离。它通过代理和路由请求来实现读写分离、查询负载,还可以做到主故障转移

1.编译安装pgpool

pgpool部署在master上

cd /usr/local/
yum install postgresql-devel
#wget https://www.pgpool.net/mediawiki/images/pgpool-II-3.6.0.tar.gz
wget https://www.pgpool.net/mediawiki/images/pgpool-II-4.5.0.tar.gz
sleep 3
tar xvf pgpool-II-4.5.0.tar.gz cd pgpool-II-4.5.0/
./configure --prefix=/usr/local/pgpool -with-pgsql=/usr/local/pgsql  -with-pgsql=/usr/local/pgdata
sleep 2
make && make install
chown -R postgres.postgres /usr/local/pgpool

2.配置准备

su - postgres
#1.配置权限文件pool_hba.conf
echo "host    all         all         0.0.0.0/0             md5" >  /usr/local/pgpool/etc/pool_hba.conf

#2.配置总配置文件pgpool.conf
cat > /usr/local/pgpool/etc/pgpool.conf << EOF
# pgpool.conf
#basic
backend_clustering_mode = 'logical_replication'
listen_addresses = '*'
port = 9999
pcp_listen_addresses = '*'
pcp_port = 9898
listen_backlog_multiplier = 2

#Backend
backend_hostname0 = 'pg1'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/usr/local/pgdata'
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_application_name0 = 'server0'

backend_hostname1 = 'pg2'
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/usr/local/pgdata'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_application_name1 = 'server1'


#auth
enable_pool_hba = on
pool_passwd = 'pool_passwd'
authentication_timeout = 1min

#ssl
ssl = off

#pool
process_management_mode = static
num_init_children = 32
max_pool = 2000

# 日志文件路径
log_directory = '/usr/local/pgpool/etc'

# # 日志文件的最大大小
log_filename = 'pg.log'
log_line_prefix = '[%m] '
log_statement = 'ddl'

#识别负载和SQL
load_balance_mode = on
ignore_leading_white_space = on
allow_sql_comments = on

# - Health Check -
health_check_period = 5
health_check_timeout = 30
health_check_user = 'postgres'
health_check_password = 'Aa532733691'
health_check_max_retries = 3
health_check_retry_delay = 1

# REPLICATION
#------------------------------------------------------------------------------

# - Streaming Replication Check -
sr_check_period = 0
sr_check_user = 'sr_check_user'
sr_check_password = 'Aa532733691'
sr_check_database = 'postgres'

# FAILOVER AND FAILBACK
failover_command = '/usr/local/pgpool/etc/failover.sh %H %R'
EOF

#3.配置密码文件pool_passwd,执行命令自动生产pool_passwd
pg_md5 --md5auth --username=nobody "Aa532733691"
pg_md5 --md5auth --username=pgsql "Aa532733691"
pg_md5 --md5auth --username=pgpool "Aa532733691"
pg_md5 --md5auth --username=postgres "Aa532733691"
cat /usr/local/pgpool/etc/pool_passwd 

#4.配置pgpool和pgsql的认证文件pcp.conf
echo "pgpool:`psql -c "select * from pg_shadow;"|grep pgpool |awk '{print $13}'`" > /usr/local/pgpool/etc/pcp.conf


#5.准备故障转移脚本
 failover.sh
#!/bin/bash


api='https://open.feishu.cn/open-apis/bot/v2/hook/xxxx'
contents=""  #要发送的信息
#换行用\n 空格用\t
function dd
{
curl -X POST \
  $api \
  -H 'Content-Type: application/json' \
  -d "{
    \"msg_type\": \"post\",
    \"content\": {
        \"post\": {
            \"zh_cn\": {
                \"title\": \"服务检测报警\",
                \"content\": [
                    [
                        {
                            \"tag\": \"text\",
                            \"un_escape\": true,
                            \"text\": \"$contents\"
                        }
                    ],
                    [

                    ]
                ]
            }
        }
    }
}"
}

newmaster=$1
newpgsql=$2
contents="pgsql主服务器异常"
dd
echo "$1 $2 " >> /usr/local/pgpool/etc/lsn.log
echo "`date`"  >> /usr/local/pgpool/etc/lsn.log
ssh postgres@$newmaster -c "pgsql -U postgres postgres -c 'SELECT * FROM pg_wal_recode_lsn('0/0'); '" >> /usr/local/pgpool/etc/lsn.log
ssh postgres@$newmaster -c "pg_ctl promote -D /app/pgdata" 

3.启动服务

#启动pgpool服务
pgpool -n -d  -a /usr/local/pgpool/etc/pool_hba.conf -f /usr/local/pgpool/etc/pgpool.conf  -F /usr/local/pgpool/etc/pcp.conf > /usr/local/pgpool/etc/pg.log 2>&1 &
##pgpool -n -d > /usr/local/pgpool/pgpool.log 2>&1 &
#关闭服务
#ps aux|grep 'pgpool -n -d' |grep -v grep |awk '{print $2}'|xargs kill -15
#重新加载配置
#pgpool reload

4.查看状态

psql  -U postgres -p 9999 -d postgres
show pool_nodes;

五、pgsql定时备份和监控shell脚本

1.pgsql定时全备脚本

cat /root/allbackup.sh 
#!/bin/bash

time1=`date +%F_%H-%M-%S`
find /app/backup/20* -type d -mtime +7  |xargs rm -rf
mkdir /app/backup
#逻辑备份
#/usr/local/pgsql/bin/pg_dump  -U postgres   -p 5432 -F c  |gzip  >  /app/backup/$time1.gz
#物理备份
/usr/local/pgsql/bin/pg_basebackup -Fp --progress -D  /app/backup/`date +%F`-pgdata -R -h 10.0.0.194 -p 5432 -U repl

2.服务监控脚本

cat /root/monitor.sh 
#!/bin/bash

#api=https://open.feishu.cn/open-apis/bot/v2/hook/e618cadd-c17e-440d-bb85-87xxx  #飞书机器人webhook 地址
api='https://open.feishu.cn/open-apis/bot/v2/hook/xxxx'
contents=""  #要发送的信息
#换行用\n 空格用\t
function dd
{
curl -X POST \
  $api \
  -H 'Content-Type: application/json' \
  -d "{
    \"msg_type\": \"post\",
    \"content\": {
        \"post\": {
            \"zh_cn\": {
                \"title\": \"服务检测报警\",
                \"content\": [
                    [
                        {
                            \"tag\": \"text\",
                            \"un_escape\": true,
                            \"text\": \"$contents\"
                        }
                    ],
                    [

                    ]
                ]
            }
        }
    }
}"
}

#pgpool启动命令
#pgpool -n -d > /usr/local/pgpool/pgpool.log 2>&1 &
#pgpool关闭命令
#pgpool -m fast stop

#pgsql启动命令
#su - postgres -c "/usr/local/pgsql/bin/pg_ctl start"
#pgsql关闭命令
#su - postgres -c "/usr/local/pgsql/bin/pg_ctl stop"

for i in `seq 3`;do 
  sleep 60
  ps aux |grep 'pgpool -n -d' |grep -v grep
  if [ $? = 0 ];then
    echo aa
    #contents="test"
    #dd
    #pgpool -n -d > /usr/local/pgpool/pgpool.log 2>&1 &
  else
    contents="`cat /etc/hostname`  pgpool数据库负载服务异常,重启中"
    dd
    su - postgres -c "/usr/local/pgpool/bin/pgpool -n -d > /usr/local/pgpool/pgpool.log 2>&1 &"
    echo "`date` pgpool异常" >> /root/momitor.log
  fi
  ps aux |grep '/usr/local/pgsql/bin/postgres' | grep -v grep
  if [ $? = 0 ];then
    echo aa
    #contents="test1"
    #dd
    #pgpool -n -d > /usr/local/pgpool/pgpool.log 2>&1 &
  else
    content="`cat /etc/hostname` pgsql数据库负载服务异常,重启中"
    dd
    su - postgres -c "/usr/local/pgsql/bin/pg_ctl start"
    echo "`date` pgsql异常" >> /root/momitor.log
  fi
done

六、pgbouncer代理中间件

1.pgbouncer介绍

2.编译安装pgbouncer

cd /usr/local
wget https://www.pgbouncer.org/downloads/files/1.20.1/pgbouncer-1.20.1.tar.gz
tar xvf pgbouncer-1.20.1.tar.gz 
cd pgbouncer-1.20.1/
#安装依赖
yum -y install make libevent libevent-devel pgkconfig openssl openssl-devel
#编译安装
./configure --prefix=/app/pgbouncer
make && make install

3.准备配置文件

cd /app/pgbouncer/share/doc/pgbouncer

#查询数据库账户密码并按格式写入账户文件
psql -c 'select usename,passwd from pg_shadow;' |sed '1,2d'|sed '$d' |sed '$d'|awk -F '|' '{print $1,$2}'|sed "s/\([^ ]\+\)/\"\1\"/g"|sed 's/^[[:space:]]*//' > userlist.txt

#总配置文件pgbouncer.ini。readyonly为数据库连接账户且只读权限,后面dbname是真实数据库名
pgbouncer.ini配置文件分两部分
第一部分是[databases]区域,是用来配置数据库连接相关信息的。
第二部分是[pgbouncer],是pgbouncer自身的配置。
cat > pgbouncer.ini << EOF
[databases]
a1 = host=127.0.0.1 port=35432 dbname=postgres
readyonly = host=10.0.0.193 port=5432 dbname=postgres
readywrite = host=10.0.0.192 port=5432 dbname=postgres
[pgbouncer]
listen_addr=*
listen_port=6432
auth_type=md5
auth_file=/app/pgbouncer/share/doc/pgbouncer/userlist.txt
logfile=/app/pgbouncer/pgbouncer1.log
pidfile=/app/pgbouncer/pgbouncerl.pid
unix_socket_dir = /tmp
max_client_conn=1000
default_pool_size=50
EOF

4.启动服务

/app/pgbouncer/bin/pgbouncer -d /app/pgbouncer/share/doc/pgbouncer/pgbouncer.ini

5.查询服务状态

#pgbouncer为默认的虚拟数据库
psql -p 6432 -U pgbouncer pgbouncer
pgbouncer=#show help; #查看帮助
pgbouncer=#SHOW DATABASES;
posted @ 2024-04-02 14:27  A学无止境A  阅读(42)  评论(0编辑  收藏  举报