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例如網絡故障尚未完成同步時使用歸檔文件來恢復數據之用。
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