[文章] PostgreSQL HA 建置 - DRBD & Heartbeat

建置的大致流程如下:
1. 設定網路相關設定,以及針對各服務開放防火牆
2. 安裝各項套件
3. 設定 DRBD
4. 設定 Postgresql
5. 設定 Heartbeat
6. 簡單的狀態監控

為達到資料庫 PostgreSQL DB 的高可用度
採用 Active/Passive 的 DB Cluster 架構
在主要 DB crash 時能自動切換到另一台 DB,維持資料庫的正常運作

這邊先列出參考先進的文章:
How To Set Up An Active/Passive PostgreSQL Cluster With Pacemaker, Corosync, And DRBD (CentOS 5.5)
Linux HA - DRBD & Heartbeat
HA-DRBD Heartbeat 建置 MySQL 高可用性

----------------------------------------------事前準備---------------------------------------------------

架構上用兩台伺服器建置 Postgresql HA
因為需要分配獨立的硬碟或分割區給兩台伺服器上的 DRBD 服務,用以同步 DB 的資料
所以在兩台伺服器上都保留 /dev/sdb 這顆硬碟給 DRBD 使用,且硬碟容量要相同

先說明一下作業系統及資料庫版本,還有網路的基本資訊
兩台伺服器的 OS 皆為 CentOS 6.3
兩台資料庫的 DB 皆為 PostgreSQL 8.4.13
主要伺服器電腦名稱為 Node1,對外 IP(eth0) 為 192.168.1.1,和另一台伺服器串接的 heartbeat IP
(eth1)為 10.1.1.1
次要伺服器電腦名稱為 Node2,對外 IP(eth0) 為 192.168.1.2,和另一台伺服器串接的 heartbeat IP(eth1)為 10.1.1.2
以 Heartbeat 虛擬出來的 Cluster IP 為 192.168.1.3,此 IP 即為 Web Server 要連接資料庫時使用的 IP
Web Server 的 IP 為 192.168.1.4


建置的大致流程如下:
1. 設定網路相關設定,以及針對各服務開放防火牆
2. 安裝各項套件
3. 設定 DRBD
4. 設定 Postgresql
5. 設定 Heartbeat
6. 簡單的狀態監控

ps. 以下未特別註明者代表兩台伺服都要執行或設定

----------------------------------------------開始設定---------------------------------------------------

1. 網路相關設定

在 Node 1 上設定 /etc/hosts
#vi /etc/hosts

127.0.0.1  Node1.com.tw Node1 localhost.localdomain localhost

192.168.1.1     Node1.com.tw Node1

192.168.1.2     Node2.com.tw Node2


在 Node 2 上設定 /etc/hosts
#vi /etc/hosts

127.0.0.1  Node2.com.tw Node2 localhost.localdomain localhost

192.168.1.1     Node1.com.tw Node1

192.168.1.2     Node2.com.tw Node2

 

設定防火牆以利兩台伺服器的 DB & DRBD & Heartbeat port 可互通
#vi /etc/sysconfig/iptables

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7789 -j ACCEPT    # for DRBD

-A INPUT -m state --state NEW -m tcp -p tcp --dport 5432 -j ACCEPT    # for Postgresql

-A INPUT -m state --state NEW -m udp -p udp --dport 694 -j ACCEPT    # for Heartbeat


2. 安裝各項套件

安裝資料庫
#yum -y install postgresql-server postgresql

安裝 DRBD

#yum -y install drbd84-utils kmod-drbd84

若找不到 DRBD 可以先執行下列指令
#wget http://elrepo.org/linux/elrepo/el6/i386/RPMS/elrepo-release-6-4.el6.elrepo.noarch.rpm
#rpm -Uvh elrepo-release-6-4.el6.elrepo.noarch.rpm


安裝 Heartbeat
#yum -y install heartbeat resource-agents

若找不到 Heartbeat 可以先執行下列指令
#wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
#rpm -Uvh epel-release-6-8.noarch.rpm


執行一次完整的 yum 更新
#yum clean all
#yum check-update
#yum update -y


設定 Postgresql 不要開機自動啟動,因為會由 Heartbeat 來啟動它,但 Heartbeat 和 DRBD 要開機自動啟動
#chkconfig postgresql off
#chkconfig drbd on
#chkconfig heartbeat on


3. 設定 DRBD

設定主要設定檔
#vi /etc/drbd.d/global_common.conf

global {

    usage-count no;

}

common {

    syncer { rate 100M; }

    protocol      C;

}

resource postgres {

    startup {

       wfc-timeout 0;

       degr-wfc-timeout

       120;

    }

    net {

       after-sb-0pri discard-zero-changes;

       after-sb-1pri discard-secondary;

       after-sb-2pri disconnect;

    }

    on Node1 {

       device      /dev/drbd0;

       disk        /dev/sdb;

       address     10.1.1.1:7789;

       meta-disk   internal;

    }

    on Node2 {

       device      /dev/drbd0;

       disk        /dev/sdb;

       address     10.1.1.2:7789;

       meta-disk   internal;

    }

}


啟動 DRBD 服務
#/etc/init.d/drbd start

建立裝置的 Metadata
#drbdadm create-md postgres

在 Node1 上執行, 指定 Node1 為 Primary node
#drbdadm -- --overwrite-data-of-peer primary postgres

4. 設定 Postgresql


僅在 Node1 針對 DRBD 磁區執行格式化
#mkfs.ext4 /dev/drbd0

僅在 Node1 將 DRBD 磁區掛載為 Postgresql 目錄
#mount -t ext4 /dev/drbd0 /var/lib/pgsql

僅在 Node1 設定 Postgresql 目錄的擁有者和群組為 postgres
#chown postgres:postgres /var/lib/pgsql


僅在Node1初始化資料庫
#su - postgres
$initdb /var/lib/pgsql/data
$exit


僅在 Node1 將 Web Server IP 設定為信任的來源授權
#echo "host all all 192.168.1.4/32 md5" >> /var/lib/pgsql/data/pg_hba.conf

僅在 Node1 設定 postgresql.conf
#vi /var/lib/pgsql/data/postgresql.conf

listen_addresses = '0.0.0.0'     # 服務 listen 在所有 IP 上

max_connections = 100           # (change requires restart) 此為預設值,需依實際狀況調整

shared_buffers = 24MB           # min 128kB,需依實際狀況調整


因為 Postgresql 的效能是需要 tuning 才能達到最佳化
以下先簡單的針對最大連線數的部份說明

查看 Postgresql 最大連線數設定
postgres> SHOW max_connections;
postgres> SELECT * FROM   pg_settings WHERE  name = 'max_connections';


查看 postgresql 的所有設定值
postgres> SHOW ALL;
postgres> SELECT * FROM pg_settings;


查看 postgresql當下的連線數
postgres> SELECT count(*) FROM pg_stat_activity;
postgres> SELECT datname, count(*) FROM pg_stat_activity GROUP BY datname;


詳細的設定和 tuning 說明可參考官方的資料
http://www.postgresql.org/docs/8.4/static/runtime-config-connection.html
http://www.postgresql.org/docs/8.4/static/kernel-resources.html#SYSVIPC
http://www.postgresql.org/docs/9.1/static/runtime-config-resource.html

http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server


僅在 Node1 啟動 Postgresql
#/etc/init.d/postgresql start

 

僅在 Node1 設定預設資料庫管理帳號 postgres 的密碼
#psql -U postgres
postgres> ALTER ROLE postgres WITH PASSWORD 'pw';


5. 設定 Heartbeat

設定主要設定檔
#vi /etc/ha.d/ha.cf

debugfile /var/log/ha-debug     #heartbeat 除錯記錄檔

logfile /var/log/ha-log         #heartbeat 記錄檔

logfacility local0              #記錄檔的記錄等級

autojoin none

ucast eth0 192.168.1.1          #填入要監控的 IP

ucast eth0 192.168.1.2          #填入要監控的 IP

udpport 694                     #使用 UDP Protocol 及 694 Port 來通訊

warntime 20                     #網路發生狀況時告警時間(秒)

deadtime 30                     #網路斷線狀況發生幾秒則判定網路出問題

initdead 30                     #主機若重開機,等待網路開啟或其他應用程式執行的時間(秒)

ping 192.168.1.254        #偵測 Gateway IP 確認網路是否正常

keepalive 1                     #每幾秒 Node 互相偵測一次 (使用 ping)

respawn hacluster /usr/lib64/heartbeat/ipfail #當網路斷線時會自動執行此程式做切換動作

node Node1

node Node2

auto_failback off               #當 Primary Node 發生問題 Secondary Node 接手後若本來的 Primary Node 修復後是否要把目前的 Primary Node 搶回

crm no


設定 HA 的資源及磁區和 Cluster 虛擬 IP
#vi /etc/ha.d/haresources

Node1 192.168.1.3 drbddisk::postgres Filesystem::/dev/drbd0::/var/lib/pgsql::ext4 postgres


在 Node1 上建立驗證檔案
#(echo -ne "auth 1\n1 sha1 "; echo $RANDOM | openssl sha1 | awk '{print $2}') > /etc/ha.d/authkeys

設定 authkeys 權限為 600
#chmod 600 /etc/ha.d/authkeys

複製 authkeys 到 Node2
#scp /etc/ha.d/authkeys root@192.168.1.2:/etc/ha.d

建立 Heartbeat 用以啟動 Postgresql 的啟動 script
#vi /etc/ha.d/resource.d/postgres

#!/bin/bash

 . /etc/ha.d/shellfuncs

 case "$1" in

 

 start)

   res=`/etc/init.d/postgresql start`

   ret=$?

   ha_log $res

   exit $ret

   ;;

 

 stop)

   res=`/etc/init.d/postgresql stop`

   ret=$?

   ha_log $res

   exit $ret

   ;;

 

 status)

   if [[ `ps -ef|grep postmaster|head -n 1|cut -d' ' -f 1` == "postgres" ]]; then

      echo "running"

   else

      echo "stopped"

   fi

   ;;

 *)

   echo "Usage: postgresql {start|stop|status}"

   exit 1

   ;;

 esac

 

 exit 0


設定 script 權限為 755
#chmod 755 /etc/ha.d/resource.d/postgres


兩台都啟動Heartbeat
#/etc/init.d/heartbeat start


6. 簡單的狀態監控

/dev/drbd0 磁區只會掛載在主要服務主機的 /var/lib/pgsql 掛載點下

#df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/drbd0            2.0T  3.5G  1.9T   1% /var/lib/pgsql


Postgresql 亦只會在主要服務主機上運作
#/etc/init.d/postgresql status

postmaster (pid  41872) is running...


在 Node1 查看 DRBD 服務狀態
顯示 Primary/Secondary,Primary 在前面代表此台為主要服務主機
#cat /proc/drbd

 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----

    ns:975641740 nr:1185956 dw:977154776 dr:985917 al:73 bm:22 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


#/etc/init.d/drbd status

m:res       cs         ro                 ds                 p  mounted         fstype

0:postgres  Connected  Primary/Secondary  UpToDate/UpToDate  C  /var/lib/pgsql  ext4


在 Node2 查看 DRBD 服務狀態
顯示 Secondary/Primary,Secondary 在前面代表此台為次要服務主機
#cat /proc/drbd

 0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----

    ns:887988 nr:975706168 dw:976594156 dr:657529 al:33 bm:12 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


#/etc/init.d/drbd status

m:res       cs         ro                 ds                 p  mounted  fstype

0:postgres  Connected  Secondary/Primary  UpToDate/UpToDate  C


Heartbeat 服務狀態
#/etc/init.d/heartbeat status

heartbeat OK [pid 2793 et al] is running on Node1 [Node1]...

 

heartbeat OK [pid 8260 et al] is running on Node2 [Node2]...


Cluster 虛擬 IP 只會設定在主要服務主機
#ip addr

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000

    inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0

    inet 192.168.1.3/24 brd 192.168.1.255 scope global secondary eth0:0

3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000

    inet 10.1.1.1/24 brd 10.1.1.255 scope global eth1


若有特殊需求需要手動切換 Active/Passive 的角色時
可以在主要服務主機(服務正在運作的主機)中執行指令強制將服務切換到另一台主機上
#/usr/share/heartbeat/hb_standby

2013/07/07_15:10:43 Going standby [all].

 

 

 


從諮商輔導人心
到諮商輔導資訊系統及網路世界
雖繞了一大圈 但都是極具意義的事
秉持著過去所學 朝著自己的興趣
體驗著一輩子只有一次的人生~~