PostgreSQL 數據庫的 primary、standby 架設

Standby技術基於PostgreSQL的預寫入日誌(wal)同步機制,建立服務器級別的數據同步節點。
在以前的版本中,我們通常使用PostgreSQL的配置項 archive_cmmand將 wal 存檔於一個指定的路徑,
standby使用recovery 配置項 restore_command指定一個系統命令,自行獲取需要恢復的wal;standby節點不提供讀操作。僅限於做備份節點。

PostgreSQL9.0 版本的 Standby的改進。
快速同步:允許儘快的 將處理中的wal發佈出去。
流式同步:允許standby節點連接到primary節點,以流式獲取新的wal 數據,達到實時的 hot standby。
數據壓縮:允許使用壓縮方式傳輸wal,節省帶寬。
standby節點可讀:當standby節點打開hot standby選項,可以實時進行讀查詢。

配置環境:

primary:10.0.0.2
Standby:10.0.0.3
兩臺服務器已經安裝好PostgreSQL9.0版本
操作系統基於 FreeBSD 8.1 (Linux下操作應該差不多)

以下操作均使用系統預置數據庫操作用戶 pgsql 操作

初始化數據庫:  pg_ctl -D /data/primary initdb

1、Primary服務器配置(10.0.0.2)
設置同步賬號
       直接使用 pgsql 系統用戶。

修改訪問控制
vim pg_hba.conf
最後添加以下內容
host replication     pgsql     10.0.0.3/32     trust   #直接使用IP地址驗證,不需要密碼

修改postgresql服務配置文件
vim postgresql.conf

主要配置修改如下
wal_level = hot_standby
archive_mode = on
archive_command = 'cp -i %p patchto_archive/%f </dev/null'
archive_timeout = 600
max_wal_senders = 1
wal_keep_segments = 16

我的postgresql.conf 配置文件配置項  

listen_addresses = '*' 
max_connections = 200  
#unix_socket_directory = '/var/postgres/primary'
shared_buffers = 1024MB
temp_buffers = 128MB
work_mem = 8MB 
wal_level = hot_standby
archive_mode = on  
archive_command = '/var/postgres/shell/pgsql_backup.sh archive %p %f'
archive_timeout = 600
max_wal_senders = 5
wal_sender_delay = 1s
wal_keep_segments = 32
hot_standby = on
log_destination = 'syslog'
syslog_facility = 'LOCAL1'
silent_mode = on
log_min_duration_statement = 1000
log_checkpoints = on
log_line_prefix = '<%h|%u>'
update_process_title = off
bytea_output = 'escape'
datestyle = 'iso, ymd'
lc_messages = 'zh_CN.UTF-8'
lc_monetary = 'zh_CN.UTF-8'
lc_numeric = 'zh_CN.UTF-8' 
lc_time = 'zh_CN.UTF-8'
default_text_search_config = 'pg_catalog.simple'
可在vim裏使用下來替換方式獲取定義的配置項
vim postgresql.conf
:%s/^\t\{1,\}//g
:%s/^ \t\{1,\}//g
:%s/^#.\{1,\}\n//g
:%s/#.*//g
:g/^\s*$/d
:%s/\t//g

配置說明參考網址
http://blog.163.com/czg_e/blog/static/46104561201141111445789/

創建socket目錄
mkdir -p -m 700 /var/postgres/primary

啓動Primary服務器數據庫進程
pg_ctl -D /data/primary start


2、創建standby數據庫恢復點備份(Primary庫)
cd /data/primary
psql -h  /var/postgres/primary postgres -c "SELECT pg_start_backup('backup', true)"
#壓縮數據庫目錄並同步到standby(10.0.0.3)上
tar -czf  /tmp/primary.tar.gz *
scp /tmp/primary.tar.gz [email protected]:/data
psql -h  /var/postgres/primary postgres -c "SELECT pg_stop_backup()"

3、standby服務器配置

mkdir -m 700 /data/standby
cd /data/standby
tar -zxf  /data/primary.tar.gz -C .
rm -f  postmaster.*

修改postgresql.conf 
hot_standby = on 

創建 recovery.conf 文件
standby 服務端  recovery.conf 文件內容

standby_mode  = 'on'
primary_conninfo  = 'host=10.0.0.2 port=5432 user=pgsql'
trigger_file = '/var/postgres/standby/standby_trigger'
restore_command = 'tar -zxf /var/postgres/primary/archive/%f.tar.gz && mv %f %p'

trigger_file 配置項的作用爲當配置項中指定的文件被創建出來,standby 節點將退出standby模式,數據庫不再與primary節點同步,並提供寫操作。
restore_command 配置項的作用僅在由於某些原因當主DB上已經完成歸檔,而standby例如網絡故障尚未完成同步時使用歸檔文件來恢復數據之用。

當然還有一個前提條件就是已經將主DB上的歸檔文件同步到輔DB的對於目錄中。

啓動standby數據庫系統
pg_ctl -D /data/standby start
檢查數據庫日誌,是否正常啓動


實驗中安裝了 pgpool-II 組件,該組件可實現自動將寫操作分配到primary庫,讀操作可實現primary、standby共同分擔。

功能看上去很誘人,本想利用該組件實現實現postgreSQL數據庫的自動主備切換,實現數據庫的更高的可用性。

但後來的負載測試結果讓人大跌眼界,性能實在是太爛。(使用sysbench測試)


附:

FreeBSD系統上需要修改幾個系統運行參數

下面的數值爲postgresql.conf 中配置200個socket連接的系統配置值(系統需重啓生效)
/etc/sysctl.conf
kern.ipc.shmall=2105344
kern.ipc.shmmax=8931270656
kern.ipc.semmap=256

/boot/loader.conf 
kern.ipc.semmni=256
kern.ipc.semmns=1024
kern.ipc.semmnu=256

系統日誌配置

/etc/syslog.conf
local1.*;local1.!warning /var/postgres/log/postgresql.log
local1.warning                             /var/postgres/log/postgresql-warning.log


自啓動配置(/etc/rc.conf)

primary庫
postgresql_enable="YES"
postgresql_data="/data/primary"

standby庫
postgresql_enable="YES"
postgresql_data="/data/standby"


pgsql_backup.sh 數據庫歸檔腳本

可實現數據庫的完整備份、wal歸檔、pg_xlog的同步和舊備份或歸檔的清理功能

將使用不同參數的該腳本加入到計劃任務中執行  (/etc/crontab)

#每5分鐘同步一次 pg_xlog目錄中的尚未完成歸檔的日誌文件
*/5     *       *       *       *       pgsql  /var/postgres/shell/pgsql_backup.sh xlog > /dev/null 2>&1
#刪除4天前的備份及歸檔
40      1       *       *       *       pgsql  /var/postgres/shell/pgsql_backup.sh clean 4 > /dev/null 2>&1 
#數據庫完整備份
0       2       *       *       *       pgsql  /var/postgres/shell/pgsql_backup.sh base > /dev/null 2>&1

文件  pgsql_backup.sh 

#!/usr/local/bin/bash

# 備份PostgreSQL數據庫
# 支持以下命令:
# base: 進行一個基礎備份
# archive: 歸檔數據庫日誌(用於設置postgresql.conf中的archive_command參數)
# xlog: 複製當前部分填充的日誌段

dbname='mydb'
database=database_path/mydb
backup=backup_path/mydb

psql_cmd=/usr/local/bin/psql
sync_cmd=/usr/local/bin/rsync

base()
{
        local v=$(date "+%Y%m%d")
        local d="$backup/base"

        if [ ! -d $d ]; then
                mkdir -p "$d"
        fi

        if [ -f "$d/base_$v.tar.gz" ]; then
                return 1
        fi

        RUN=`ps ax | grep 'pgsql_backup.sh base' | grep -v grep | wc -l`
        if [ "$RUN" -gt 2 ]; then 
                echo "backup is already running"
                exit 1 
        fi 

        vacuumdb -afz
        $psql_cmd template1 -c "select pg_start_backup('$v');"       
        (cd "$database"; tar -czf $d/$dbname"_"$v".tar.gz"  $(ls | sed 's/pg_xlog//') )
        $psql_cmd template1 -c "select pg_stop_backup();"
}

# archive_command = '/pathto/pgsql_backup.sh archive %p %f'
archive()
{
        local p="$1"
        local f="$2"

        if [ "$p" = "" ] || [ "$f" = "" ] || [ -f "$backup/archive/$f.tar.gz" ]; then
                return 1
        fi

        if [ ! -d "$backup/archive" ]; then
                mkdir -p "$backup/archive"
        fi
        #cp -a "$p" "$backup/archive/$f"
        #使用打包壓縮處理歸檔日誌文件,數據量將大大減小,當數據庫較繁忙時建議不採用壓縮方式歸檔
        #使用壓縮方式歸檔在做數據庫恢復操作時 restore_command 使用
        # restore_command = 'tar -zxf archive_patch/%f.tar.gz && mv %f %p'
        #否則恢復失敗
        cd pg_xlog && tar -czf "$backup/archive/$f.tar.gz" "$f"
}

xlog()
{
        if [ -d "$database/pg_xlog" ]; then
                mkdir -p "$database/pg_xlog"
        fi
        $sync_cmd -a --delete "$database/pg_xlog" "$backup"
}

clean()
{
    local t=$(echo "$1" | grep -E '^[0-9]{1,2}$')
    if [ "$t" = "" ]; then
        #echo "Day Number '$1' error"
        return 1
    fi

    find $backup/archive -mindepth 1 -maxdepth 1 -mtime +"$1" -exec rm -rf {} \;
    find $backup/base -mindepth 1 -maxdepth 1 -mtime +"$1" -exec rm -rf {} \;
    #echo "done."
}


case $1 in
        base)
                base
                ;;
        archive)
                archive "$2" "$3"
                ;;
        xlog)
                xlog
                ;;
        clean)
                clean "$2"
                ;;
        *)
                echo "usage: $0 {base|archive|xlog|clean}"
                exit 1
                ;;
esac
        




發佈了38 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章