2011年12月6日 星期二

轉:Postgresql熱備機之間切換


初步實驗出了兩台熱備機不用重新做一次完整的基礎備份也能切換並保持資料不丟失。最開始的一次基礎備份避免不了,資料是否絕對不丟失我也不敢完全確定,大家可以來做測試。實驗過程如下:

A
B兩台伺服器(虛擬機器)postgresql-8.4.5 + centos-4.8
AB
之間配了ssh,可以互相scpA一開始是activeBstandby

A
postgresql.conf
開啟歸檔模式:
Quote:


archive_mode = on
archive_command = 'cp %p /tmp/db/wal/%f'
archive_timeout = 6000


wal archive
目錄為/tmp/db/wal/A機上跑下面的腳本,主要作了初始化工作,並且在pg_start_backup()後打包/var/lib/pgsql/data目錄供B使用。
Quote:


#!/bin/sh

SUDO="sudo -u postgres"

service postgresql stop
rm -rf /var/lib/pgsql
rm -rf /tmp/db/wal/*
service postgresql initdb

cp -a -f postgresql.conf /var/lib/pgsql/data/
cp -a -f pg_hba.conf /var/lib/pgsql/data/

service postgresql start
$SUDO createdb xxxx
psql -U postgres xxxx < xxxx.db
echo "INSERT INTO node (id,name,ipaddr) values (2,'hal','192.168.5.123')" | psql -U postgres xxxx
echo "INSERT INTO node (id,name,ipaddr) values (7,'zhizi','192.168.5.100')" | psql -U postgres xxxx

echo "select pg_start_backup('xxxx',true)" | psql -U postgres xxx
echo "insert into node (id,name,ipaddr) values (11,'nelly', '192.168.4.115')" | psql -U postgres xxxx
sleep 1
tar cf pgdata.tar /var/lib/pgsql/data/
echo "select pg_stop_backup()" | psql -U postgres xxxx


然後Aservice postgresql stop

B
跑下麵的初始化腳本,把A機上的pgdata.tar解壓到自己的/var/lib/pgsql/data
Quote:


#!/bin/sh

SUDO="sudo -u postgres"

service postgresql stop
rm -rf /var/lib/pgsql
rm -rf /tmp/db/wal/*
service postgresql initdb
rm -rf /var/lib/pgsql/data/
scp A:pgdata.tar .
rm -rf var/ tmp/
tar xf pgdata.tar
mv var/lib/pgsql/data/ /var/lib/pgsql/


複製A機上/tmp/db/wal/下所有檔到本機/tmp/db/wal下,注意許可權。編輯/var/lib/pgsql/data/recovery.cong內容為:
Quote:


restore_command='cp /tmp/db/wal/%f %p'


B
service postgresql start。可以看到之前A機新增的資料都過來了。這是最普通的恢復過程,下面進行切換,A再次成為active

=================
切換===================
注意:B機資料庫起來後把/tmp/db/wal/下的舊檔刪除,以免和後來的新資料混淆。另外,B機還是以archive模式起來。

B
機上任意添加刪除些資料,service postgresql stop

ssh
A機:
刪除/tmp/db/wal/下所有檔;
scp B:/tmp/db/wal/* /tmp/db/wal/
chown postgres.postgres /tmp/db/wal/*
備份/var/lib/pgsql/data/;
vim /var/lib/pgsql/recovery.conf:
Quote:


restore_command='cp /tmp/db/wal/%f %p'
recovery_target_xid='00000002'


xid
很關鍵,確認這個值可以看看Bservice postgresql stop/tmp/db/wal/下最大的值,比如該目錄有下列檔:
[root@pg84 data]# ll /tmp/db/wal/
total 49216
-rw------- 1 postgres postgres 16777216 Jan 17 07:10 000000010000000000000004
-rw------- 1 postgres postgres 16777216 Jan 17 07:10 000000020000000000000004
-rw------- 1 postgres postgres 16777216 Jan 17 07:10 000000020000000000000005
-rw------- 1 postgres postgres 224 Jan 17 06:48 00000002.history

那麼xid就該取00000002

接著scp B:/var/lib/pgsql/data/global/pg_control,覆蓋A機上的/var/lib/pgsql/data/global/pg_control,注意許可權。

最後Bservice postgresql start,資料變更應該都過來了。

================================

以後B要再切回active也是如上步驟。三處關鍵點:


  • /tmp/db/wal/*
  • recovery.conf文件的recovery_target_xid
  • /var/lib/pgsql/data/global/pg_control


遺留問題:


  1. 這樣過來的資料是否靠譜,是否會有丟失?
  2. xid值的判斷不太容易
  3. 真正熱備場景切換是否順滑?

沒有留言: