EnterpriseDB 9.1 移機步驟 ( pg_basebackup、pg_start_backup + pg_stop_backup + rsync )

簡單描述 EnterpriseDB 9.1 在做資料庫移機的步驟,當然還會有些測試與問題

因機房要搬遷,所以在這裡記錄辛酸血淚測試過程 (XD)

移動資料庫 Enterprisedb 或是 PostgreSQL 其實在 9.1 版本上,有出一個工具 pg_basebackup,這工具在未來的版本做得很棒,要做 streaming replication 會變得非常的簡單,但對於資料庫容量過於龐大的話,建議就不要使用,後面會說明原因;對於新版本 9.6 以上是否有一樣的狀況,筆者手邊沒有新版本的大型資料庫可測,因此就當做知識瞭解即可。

環境:edb 9.1 整體資料量 500g 左右

方法1. pg_basebackup

該工具的方法我相信有在管理 PostgreSQL 或 EDB 的 dba、管理員都不陌生,來看以下工具的說明

pg_basebackup takes a base backup of a running PostgreSQL server.

Usage:
  pg_basebackup [OPTION]...

Options controlling the output:
  -D, --pgdata=DIRECTORY   receive base backup into directory
  -F, --format=p|t         output format (plain, tar)
  -x, --xlog               include required WAL files in backup
  -z, --gzip               compress tar output
  -Z, --compress=0-9       compress tar output with given compression level

General options:
  -c, --checkpoint=fast|spread
                           set fast or spread checkpointing
  -l, --label=LABEL        set backup label
  -P, --progress           show progress information
  -v, --verbose            output verbose messages
  --help                   show this help, then exit
  --version                output version information, then exit

Connection options:
  -h, --host=HOSTNAME      database server host or socket directory
  -p, --port=PORT          database server port number
  -U, --username=NAME      connect as specified database user
  -w, --no-password        never prompt for password
  -W, --password           force password prompt (should happen automatically)

而筆者就從 slave 主機上下了以下的指令,執行的過程沒有出現什麼問題

pg_basebackup -h IPAddress_Master -D /edb/data/ -U repl -p 5432 -v -x -P

不過因為傳送執行時間大約 5~6 小時,為了確保 edb、PostgreSQL 產生出來的 archive log 不被 loss 掉,因此定期傳送 archive log 到 slave 主機上

rsync -avzP /arch/pg_archivelog/* IPAddress_Slave:/backup/archivelog_standby

等待 pg_basebackup 完成後,建立 recovery.conf 讓 slave 資料庫能夠與 master 溝通做 streaming replication

restore_command = 'cp /backup/archivelog_standby/%f %p'
standby_mode = 'true'
primary_conninfo = 'host=IPAddress_Master port=5432 user=repl'
recovery_target_timeline = 'latest'
trigger_file='/tmp/standby­trigger'

然後再修改一下 slave postgresql.conf 的設定

hot_standby = on

之後就開啟服務吧~~~~!!!!!!!!

pg_ctl start -D /edb/data

如果 pg_xlog 底下的檔案不存在的話,就會使用 archive log 來還原,當還原結束後,就會與 master 主機進行 streaming replication,

進 master 下以下 sql 可以看到連線狀況,

SELECT * FROM pg_stat_replication;

查目前使用的 log 編號 ( master + slave ),會發現 master + slave 的編號會是相同的 (不同的話,要排除傳送過程是不是有 delay)

psql edb -c "select pg_current_xlog_location()"

同步過程中,測試了 create table + insert + delete + drop table 基本上都是3秒內就傳送到 slave 主機上,因此「覺得」沒什麼問題,就是因為「覺得」沒什麼問題,這才是問題

實際把資料庫交付給程式開發人員檢查,發現有部份的 Table 資料有少 😫😫

(os: 怎麼可能!!都同步成功了,表示還原就沒問題才對啊~~)

檢查後發現有少的資料的部份,是在備份期間,簡單解釋時間軸:

09:00 開始備份
15:00 備份完畢
15:00 開啟資料庫 進行 archivelog 還原
15:03 還原完畢
15:03 streaming replication 同步

而資料不見的部份就是 9:00 開始備份 -> 15:00 備份完畢 這段期間,但並非全部沒還原,而是只有吃到 10:00 前的資料,就是只還原了一小部份的資料,想說怎麼那麼奇怪,前前後後測試了3次,結果都相同,備份期間的資料都只會還原一部份,但同事測試了 edb 11 的版本,並沒有發生這個問題,因此就想說是個 bug,然後就放棄了這個方法,因為 edb 9.1 已經 EOSL 了啊…沒得問😭😭

 

方法2. pg_start_backup + rsync + pg_stop_backup (推薦)

因方法1有些問題,就想到用差異的方式來備份,但就無法像 straming replication 的 slave 可以開啟資料庫到 read only 模式,可即時知道資料同步狀況,但這個備份方法也是基礎的備份方法,因此還是要會怎麼操作

首先對 edb 下 pg_start_backup (Postgresql 也是相同操作)

psql -c "select pg_start_backup('mybackup', true)"

此時就可以用 rsync 把檔案傳送到 slave 主機上

rsync -avzrHSP -e "ssh -o ServerAliveInterval=30"  \
                 --delete /edb/* \
                 --exclude=postmaster.pid IPAddress_Slave:/edb

當 rsync 傳送完畢時,對 master 主機下達 pg_stop_backup 即可

psq -c "select pg_stop_backup()"

回到 slave 主機上,就可以開啟服務囉?

(瞇之音:這樣備份期間的資料還會有嗎?答:沒測試 XD

但是建議再做一次上面提到的步驟,rsync 是使用差異備份的方法,如果 master、slave 檔案的 checksum 不同,那麼就視為相異,就會先刪除 slave 檔案,再傳送新的檔過去覆蓋掉,因為是用差異備份的方法,所以實際上傳送的時間大約1小時內通常就會結束,比起第一次傳送 5~6 小時減少很多,所以就放在 linux crontab 上,每小時去跑大概就沒什麼問題吧!

#!/bin/bash

source /home/enterprisedb/pgplus_env.sh

rsync_gb_count=`ps -ef | grep ${0##*/} | grep -v grep | wc -l`
if [ "$rsync_gb_count" -ge 3 ]; then
        echo "Exit Shell"              
        exit 1
fi

get_count_generate_data()
{
        count="0"
        next_count=`ps -ef | grep "rsync -avzrHSP" | grep -v grep | wc -l`
        check="^[0-9]+$"
        if ! [[ $next_count =~ $check ]] ; then
                next_count="1"
        fi
        count=$(($count + $next_count))
}

get_count_generate_data
echo "Now rsync is running.  This make take a while."
echo -ne "."
while [ "$count" -gt "0" ]; do
        echo -ne "."
        sleep 5
        get_count_generate_data
done

echo "Begin_`date`">> /backup/script/rsync.log
psql -c "select pg_start_backup('mybackup', true)"

if [ $? -eq 0 ]; then
    rsync -avzrHSP -e "ssh -o ServerAliveInterval=30"  \
                 --delete /edb/* \
                 --exclude=postmaster.pid IPAddress_Slave:/edb \
                 >> /backup/script/rsync.log
fi

psql -c "select pg_stop_backup()"
echo "End_`date`">> /backup/script/rsync.log

至於 script 寫的好不好,又是另一回事,能用的順利不卡卡,就是好工具 XD

以上內容僅供參考,若有錯誤的地方,還請讀者們給予提醒修正

 

相關資料來源:

Taking a backup of a streaming WAL slave https://dba.stackexchange.com/questions/48103/taking-a-backup-of-a-streaming-wal-slave

已轉向 blogger 記錄

https://slowlife-notes.blogspot.com