乐趣区

PostgreSQL主从部署

环境描述

自行下载 rpm 包本地安装或者 wget 创建 PostgreSQL 的源文件。本次记录为内网服务器,rpm 本地安装,版本为 PostgreSQL-9.6,经测试,9.6 主从流复制可切换,9.4 测试未果。

位于 /share/rpms/psql-need/ 目录下。

机器规划

Master server

系统版本 机器配置 主机名 IP
CentOS Linux release 7.4.1708 48C/256G/33TB Bus-App-21 190.176.35.170
CentOS Linux release 7.4.1708 48C/256G/33TB Bus-App-22 190.176.35.171

Master Server

以下命令在 rpm 包目录下执行。

# yum install ./postgresql96\*

# mkdir -p /data/pgsql-9.6/archive

# chown postgres.postgres /data/pgsql-9.6

# chmod 0700 /data/pgsql-9.6

# vim /usr/lib/systemd/system/postgresql-9.6.service

Environment=pgsql-9.6=/data/pgsql-9.6/

# /usr/pgsql-9.6/bin/initdb -D /data/pgsql-9.6

# systemctl enable postgresql-9.6

# systemctl start postgresq-9.6

# passwd postgres

# su postgres

$ psql –U postgres

=$ alter user postgres with password‘Ur passwd’;

=$\q

# vim /data/pgsql-9.6/postgresql.conf

listen_addresses = '*'

max_connections = 500

superuser_reserved_connections = 5

shared_buffers = 128MB

dynamic_shared_memory_type = posix

wal_level = hot_standby

synchronous_commit = local

archive_mode = on

archive_command = 'cp %p /data/pgsql-9.6/archive/%f'

max_wal_senders = 5

# vim /data/pgsql-9.6/pg_hba.conf

host    replication     postgres        127.0.0.1/32              md5

host    replication     postgres        190.176.35.0/24                 md5

# systemctl restart postgresql-9.6

Slave Server

以下命令在 rpm 目录下执行。

# yum install postgresql96*

# vim /usr/lib/systemd/system/postgresql-9.6.service

Environment=pgsql-9.6=/data/pgsql-9.6/

# mkdir -p /data/pgsql-9.6/archive

# chown postgres.postgres /data/pgsql-9.6

#chmod 0700 /data/pgsql-9.6

# su postgres

$ pg_basebackup -h 190.176.35.170 -U postgres -D /data/pgsql-9.6 -P --xlog

$ vim /data/pgsql-9.6/postgresql.conf

hot_standby = on

max_connections = 510 #于主库数值

max_wal_senders = 5

$ cp /usr/pgsql-9.6/share/recovery.conf.sample /data/pgsql-9.6/

$ mv /data/pgsql-9.6/recovery.conf.sample /data/pgsql-9.6/recovery.conf

$ vim /data/pgsql-9.6/recovery.conf

recovery_target_timeline = 'latest'

standby_mode = on

primary_conninfo = 'host= 主库’s IP port=5432 user=postgres password= 密码'

trigger_file = '/data/pgsql-9.6/trigger.pg

$ exit

# systemctl enable postgresql-9.6

# systemctl start postgresql-9.6

测试

在 Master 所在服务器查看状态:

$ psql -c "select application_name,state,sync_priority,sync_state from pg_stat_replication"

application_name |   state   | sync_priority | sync_state

------------------+-----------+---------------+------------

 Bus-App-22       | streaming |             1 | sync

(1 row)

测试复制功能

Keepalived-1.2

自行安装软件并测试使用

配置文件配置 exm 如下

# cat /etc/keepalived/keepalived.conf

global_defs {

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id pg

}

vrrp_script chk_pgsql {

   script "/etc/keepalived/scripts/pgsql_check.sh"

   interval 1

   weight 2

}

vrrp_instance VI_1 {

    state MASTER #备机为 BACKUP

    interface enp2s0f0

    virtual_router_id 61

    priority 100 #备机为 80

    nopreempt

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    track_script {chk_pgsql}

    virtual_ipaddress {190.176.35.210}

}

测试 vip 的浮动

Keepalived 脚本

脚本路径可自己在 keeplived.conf 中定义,注意脚本权限。

# cat /etc/keepalived/scripts/pgsql_check.sh

#!/bin/bash

#判断 pg 是否活着

A=`ps -C postmaster --no-header | wc -l`

#判断 vip 浮到哪里

B=`ip a | grep 190.176.35.210 | wc -l`

#判断是否是从库处于等待的状态

C=`ps -ef | grep postgres | grep 'startup process' | wc -l`

#判断从库链接主库是否正常

D=`ps -ef | grep postgres | grep 'receiver' | wc -l`

#判断主库连接从库是否正常

E=`ps -ef | grep postgres | grep 'sender' | wc -l`

#如果 pg 死了,将消息写入日记并且关闭 keepalived
if [$A -eq 0];then
    echo "\`date"+%Y-%m-%d--%H:%M:%S"\` postgresql stop so vip stop" >> /etc/keepalived/log/check_pg.log
    systemctl stop keepalived
else
        #判断出主挂了,vip 浮到了从,创建 trigger,pg 备机进入 recovery 模式,赋予读写权限
        if [$B -eq 1 -a $C -eq 1 -a $D -eq 0 \];then
                su - postgres -c "touch /data/pgsql-9.6/[trigger.pg](http://trigger.pg/)"
                echo "`date"+%Y-%m-%d--%H:%M:%S"` standby promote" >> /etc/keepalived/log/check_pg.log
        fi
        #判断出自己是主并且和从失去联系
        if [$B -eq 1 -a $C -eq 0 -a $D -eq 0 -a $E -eq 0];then
                                sleep 10
                echo "`date"+%Y-%m-%d--%H:%M:%S"` can't find standby " >> /etc/keepalived/log/check_pg.log
        fi
fi

以下命令为手动指定 keepalived 配置文件,并启动的命令

# /usr/local/keepalived/sbin/keepalived -D -f /usr/local/keepalived/etc/keepalived/keepalived.conf

异步主从流复制主从切换与恢复 MASTER

以下红色标记的命令为流复制主从切换,与恢复 MASTER 的操作

模拟关闭主库,演练 MASTER 服务宕机

# systemcrl stop postgresql-9.6

SLAVE 上操作

在从库创建 trigger(此步骤部署于高可用脚本中,触发自动推读写数据库切换)

$ touch /data/pgsql-9.6/trigger.pg

旧备库 recovery.conf 变为 recovery.done,旧备库成为新主库

恢复操作

MASTER 上操作

$ mv /data/pgsql-9.6/recovery.done /data/pgsql-9.6/recovery.conf

如第一次触发 HA,则将 recovery.done 拷贝到 MASTER,并修改以下内容

primary_conninfo = 'host= 新主库’s IP port=5432 user=postgres password= 密码'

如第一次出发 HA,则修改 MASTER 配置文件,MASTER 现在为新备库,所以 postgersql.conf 中的 max_connections 应该大于新主库

$ vim /data/pgsql-9.6/postgresql.conf

hot_standby = on #检查是否开启

max_connections = (每次恢复都必须修改新备机的这条配置,并比新主机的大)

启动新备库与新备库的 keepalived

# systemctl restart postgresql-9.6

以上操作完后应该主备流复制 MASTER 为备 receiver,SLAVE 为主 sender。使用命令# ps -ef | grep postgres 可查看

以下一条操作 VIP 从 SLAVE 跳至 MASTER

# systemctl restart keepalived

# ip a #查看 vip 应跳回 MASTER

SLAVE 上操作

关闭新主库 postgresql 服务

# systemctl stop postgresql-9.6

$ mv /data/pgsql-9.6/recovery.done /data/pgsql-9.6/recovery.conf

$ vim /data/pgsql-9.6/postgresql.conf

max_connections = (每次恢复都必须修改新备机的这条配置,并比新主机的大)

# systemctl start postgresql-9.6

# systemctl start keepalived

以上操作完后应该主备流复制 MASTER 为备 sender,SLAVE 为主 receiver。使用命令# ps -ef | grep postgres 可查看

在 MASTER 上查看流复制状态

$ psql

postgres=# select client_addr,state,sync_state from pg_stat_replication;

  client_addr   |   state   | sync_state

----------------+-----------+------------(主库’s IP)| streaming | async

(1 row)

MASTER 为发送端,不存在 startup process 并存在 sender 进程判定为主库

$ ps -ef | grep postgres

postgres   378     1  0 11:32 pts/0    00:00:00 /usr/pgsql-9.6/bin/postgres -D /data/pgsql-9.6

postgres   379   378  0 11:32 ?        00:00:00 postgres: logger process                   

postgres   381   378  0 11:32 ?        00:00:00 postgres: checkpointer process             

postgres   382   378  0 11:32 ?        00:00:00 postgres: writer process                   

postgres   383   378  0 11:32 ?        00:00:00 postgres: wal writer process               

postgres   384   378  0 11:32 ?        00:00:00 postgres: autovacuum launcher process      

postgres   385   378  0 11:32 ?        00:00:00 postgres: archiver process                 

postgres   387   378  0 11:32 ?        00:00:00 postgres: stats collector process          

postgres   464   378  0 11:47 ?        00:00:00 postgres: wal sender process postgres 192.168.40.185(50096) streaming 0/90038A0

root      1293  1258  0 14:13 pts/1    00:00:00 su postgres

postgres  1294  1293  0 14:13 pts/1    00:00:00 bash

postgres  1417  1294  0 14:38 pts/1    00:00:00 ps -ef

postgres  1418  1294  0 14:38 pts/1    00:00:00 grep postgres

SLAVE 为接收端,存在 startup process 与 wal receiver 进程并存则判定为备库

$ ps -ef | grep postgres

root      1293  1258  0 14:13 pts/1    00:00:00 su postgres

postgres  1294  1293  0 14:13 pts/1    00:00:00 bash

postgres  1448     1  0 14:43 pts/1    00:00:00 /usr/pgsql-9.6/bin/postgres -D /data/pgsql-9.6

postgres  1449  1448  0 14:43 ?        00:00:00 postgres: logger process                   

postgres  1450  1448  0 14:43 ?        00:00:00 postgres: startup process   recovering 00000003000000000000000A

postgres  1451  1448  0 14:43 ?        00:00:00 postgres: checkpointer process             

postgres  1452  1448  0 14:43 ?        00:00:00 postgres: writer process                   

postgres  1453  1448  0 14:43 ?        00:00:00 postgres: stats collector process          

postgres  1454  1448  0 14:43 ?        00:00:00 postgres: wal receiver process   streaming 0/A001060

postgres  1457  1294  0 14:44 pts/1    00:00:00 ps -ef

postgres  1458  1294  0 14:44 pts/1    00:00:00 grep postgres

测试新主库读写

测试数据同步功能

注意事项

  • 修改默认 data 目录时,要注意新目录权限必须为 0700,属主属组必须为 postgres。
  • 务必设置 postgres 用户的数据库密码:postgres=# alter user postgres with password‘Ur passwd’;,否则配置主从流复制,备机 pg_basebackup 会出现认证错误。
  • 注意 pg_hba.conf 文件的权限问题。
  • psql: FATAL: the database system is starting up. 修改配置文件 hot_standby = on。
  • Keepalived 脚本中 ps -C postmaster,如果是使用 postgres 用户启动则是 ps -C postgres,其他用户为 postmaster。
退出移动版