MathJax

MathJax-2

MathJax-3

Google Code Prettify

置頂入手筆記

EnterproseDB Quickstart — 快速入門筆記

由於考慮採用 EnterpriseDB 或是直接用 PostgreSQL 的人,通常需要一些入手的資料。這邊紀錄便提供相關快速上手的簡單筆記 ~ 這篇筆記以 資料庫安裝完畢後的快速使用 為目標,基本紀錄登入使用的範例:

2018年6月12日 星期二

PGSQL 9.6 與 PGSQL 10 的 pg_basebackup 功能差異之一

PostgreSQL 的 pg_basebackup 是資料庫全備份的工具。在這個指令出現之前,通常是自己呼叫 SELECT pg_start_backup() 與 SELECT pg_stop_backup(),搭配各自備份的功能(tarball,rsync,上磁帶指令等等),分別備份資料庫的 $PGDATA 以及 WAL 目錄內容(PGSQL 9.x 的 $PGDATA/pg_xlog/,或是 PGSQL 10 的 $PGDATA/pg_wal/)。在 PGSQL 9.1 之後,把這過程打包成 pg_basebackup 指令,簡化備份過程(讓人變懶惰??)這指令的功能也隨著版本演進而越加豐富齊全。

最近在使用上,發現一個使用細節的改進,在 PGSQL 10 上是一個重要的改進~


pg_basebackup 的參數中,除了主機連線設置之外,還有幾個關於備份的選項。其中有一個 WAL 傳輸選項 -X,將備份所需的 WAL 一起打包的方式,這保證備份檔可以獨立啟動,不會遺漏 WAL 檔案。
WAL 備份模式有兩種:
-X fetch 指的是,在 pg_basebackup 備份程序的最後,才抓取所需的 WAL 檔案
-X stream 則是,在 pg_basebackup 的備份期間,以串流傳遞的方式,不斷補上需要的 WAL 檔案

另外,全備份提供三種模式進行:
-F plain:用來建立 Streaming Replication
-F tar:不壓縮打包,常常搭配壓縮指令使用(下一項)
-F tar -z:打包並且 gzip 壓縮,可以再用 -Z 設定壓縮等級

上面的選項,並不是可以任意搭配的。這就是這篇筆記的重點。
下面為 9.x 版 pg_basebackup 備份選項的簡易搭配表:

PGSQL 9.x
-X fetch
(需要 wal_keep_segments)
-X stream
(可選搭 replication slot)
-F plain
O
O
-F tar
O
X
-F tar -z
O
X

再來則是 10 版 pg_basebackup 備份選項的簡易搭配表:

PGSQL 10
-X fetch
(需要 wal_keep_segments)
-X stream
(可選搭 replication slot)
-F plain
O
O
-F tar
O
O
-F tar -z
O
O

以下會分別用 Postgres 9.6 以及 Postgres 10 進行試驗。

為了方便測試,這裡把 max_wal_size 減小(預設 1GB),讓 pg_xlog 目錄(PGSQL10 的 pg_wal 目錄)留下來的 WAL 數量少一些,比較容易發生 WAL 太早被移除/備份的情形。
psql -c "alter system set max_wal_size = '80MB';"
pg_ctl restart

備份指令測試期間,同時使用以下指令,長時間的塞資料(看電腦速度,我的測試環境耗時半小時左右~),讓資料庫一直刷新的 WAL 檔案,並不斷的觸發向外備份
#長時間塞資料
psql -c "select id , \
(random()*100)::int num1_100 , \
(random()*10000)::text num1_1W , \
(random()*1000000)::text num1_100W \
into test_tab from generate_series(1,10000000) id;"

在上面的資料插入運作期間,進行 pg_basebackup 備份。以下分成兩部份,分別是在 Postgres 9.6 進行一次,以及在 Postgres 10 進行一次。這裡在 Linux 下的本機測試備份(以 OS 帳號 postgres 進行),因此不用特地輸入連線資訊即可。

一)在 PostgreSQL 9.6 (含)之前的版本
沒辦法同時作壓縮備份與 WAL Stream 模式的指定
bash-$ mkdir ~/pg96-backup
bash-$ pg_basebackup -U postgres -D ~/pg96-backup -F tar -X stream -P -v
pg_basebackup: WAL streaming can only be used in plain mode
Try "pg_basebackup --help" for more information.
bash-$ pg_basebackup -U postgres -D ~/pg96-backup -F tar -z -X stream -P -v
pg_basebackup: WAL streaming can only be used in plain mode
Try "pg_basebackup --help" for more information.
bash-$ 

在 PGSQL 9.4 之前,會詳細的設定 checkpoint_segments 與 wal_keep_segments 以避免 Streaming Rplication 中斷或是 pg_basebackup 備份缺少 WAL 造成不完整的狀況。
在 PGSQL 9.5 之後,由於 WAL 檔案控制模式的改變(max_wal_size & min_wal_size 取代了 checkpoint_segments),以及 Replication Slot 的使用,WAL 的設定比較簡單,但可能會因此不小心一同忘記設定 wal_keep_segments。
若不幸忘記設置 wal_keep_segments,一旦在 pg_basebackup -X fetch 備份期間發生了 WAL Rotate/Archiving,在備份最末階段,會告知備份失敗,因為 pg_xlog/ 目錄找不到需要的檔案了(儘管該 WAL 檔案被備份到 Archive 目錄)。以下簡單進行示範
bash-$ #同時在另一個 Shell 進行長時間塞資料的行為
bash-$ pg_basebackup -D ~/pg96-backup -F tar -X fetch -z -P -v
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 3/787D10F0 on timeline 1
1101661/1101661 kB (100%), 3/3 tablespaces                                         
pg_basebackup: could not get write-ahead log end position from server: ERROR:  requested WAL segment 000000010000000300000078 has already been removed
pg_basebackup: removing contents of data directory "/var/lib/postgres/pg96-backup"
bash-$ ls -l ~/pg96-backup
total 0
bash-$ 

如果要成功,需要設置「夠大的」的 wal_keep_segments 才不會失敗:在這次測試中 10 個還不夠........直接設定到 100 個,但這樣也表示 pg_xlog/ 目錄的內容可能到 1600MB 之多。
psql -c "alter system set wal_keep_segments = '100';"
pg_ctl restart
#進行長時間塞資料的行為
bash-$ pg_basebackup -D ~/pg96-backup -F tar -X fetch -z -P -v
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
transaction log start point: 4/6804DE48 on timeline 1
2025730/2025730 kB (100%), 3/3 tablespaces                                         
transaction log end point: 4/A454FE08
pg_basebackup: base backup completed
bash-$ ls -l ~/pg96-backup
total 694384
-rw-rw-r--. 1 enterprisedb enterprisedb       117 Feb  6 07:02 30254.tar.gz
-rw-rw-r--. 1 enterprisedb enterprisedb       117 Feb  6 07:02 30255.tar.gz
-rw-rw-r--. 1 enterprisedb enterprisedb 711036705 Feb  6 07:21 base.tar.gz
bash-$ 

[NOTE] 不好意思,PGSQL9.6 測試環境用的比較久,比 PGSQL10 多了兩個 Tablespace,不過不影響結論~

上面可見,要正常備份,需要設置充足的 wal_keep_segments,但這樣就得好好的拿捏這個量~





二)在 PostgreSQL 10 後,pg_basebackup -F tar -X stream 功能被增加進來,使的下面的功能可以用
bash-$ #同時在進行長時間塞資料的行為
bash-$ mkdir ~/pg10-backup
bash-$ pg_basebackup -U postgres -D ~/pg10-backup -F tar -X stream -z -P -v
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/3051400 on timeline 1
pg_basebackup: starting background WAL receiver
200570/200570 kB (100%), 1/1 tablespace                                         
pg_basebackup: write-ahead log end point: 0/28C3DB28
pg_basebackup: waiting for background process to finish streaming ...
(等待塞完資料,以及 checkpoint)
pg_basebackup: base backup completed
bash-$ 

仔細查看最後的備份內容,PGSQL 10 比起之前版本多了一個 WAL 獨立的壓縮檔,而之前版本的備份,則是把  $PGDATA/pg_xlog/ 目錄一併壓縮在 base.tar.gz 裡面
bash-$ ls -l ~/pg10-backup/
total 293888
-rw-rw-r--. 1 enterprisedb enterprisedb  66873697 Feb  5 09:44 base.tar.gz
-rw-------. 1 enterprisedb enterprisedb 234057964 Feb  5 09:49 pg_wal.tar.gz
bash-$ 

要注意的是,這裡把 PGSQL 10 的 pg_basebackup 指令對 PGSQL 10 Server 進行備份;然而,若把 PGSQL10 的 pg_basebackup 指令對 PGSQL9.6 進行 -F tar -X stream 備份則會發生錯誤
bash-$ pg_basebackup -U postgres -D ~/pg96-backup -F tar -X stream -P -v
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 3/F7000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: unexpected termination of replication stream: ERROR:  requested WAL segment 000000010000000300000000 has already been removed
642725/642725 kB (100%), 3/3 tablespaces                                         
pg_basebackup: write-ahead log end point: 3/F7000130
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: child process exited with error 1
pg_basebackup: removing contents of data directory "/var/lib/postgres/pg96-backup"
bash-$ pg_basebackup -U enterprisedb -D ~/pg96-backup -F tar -z -X stream -P -v
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 3/F9000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: unexpected termination of replication stream: ERROR:  requested WAL segment 000000010000000300000000 has already been removed
642725/642725 kB (100%), 3/3 tablespaces                                         
pg_basebackup: write-ahead log end point: 3/F9000130
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: child process exited with error 1
pg_basebackup: removing contents of data directory "/var/lib/postgres/pg96-backup"
bash-$ 

PGSQL 10 的 pg_basebackup 改進的功能,讓我們可以順利的進行備份,不用再被 wal_keep_segments 困擾~

另外,我們還可以讓 pg_basebackup -X stream 咬一個 replication slot,就可以更加保障備份過程~


參考資料

EnterpriseDB 原廠客服
其他 pg_basebackup 的筆記,可以上網查查

沒有留言:

張貼留言