標籤:
基本環境說明:
os:FreeBSD 9.3postgresql version:9.3.6master:192.168.56.101standby:192.168.56.102
安裝過程略,基於pkg包
1.配置master端
# psql -U pgsql -d postgres -c "CREATE USER rep REPLICATION LOGIN ENCRYPTED PASSWORD ‘password‘;"
# cd /usr/local/pgsql# vim data/postgresql.conflisten_addresses = ‘*‘wal_level = ‘hot_standby‘max_wal_senders = 1# vim data/pg_hba.confhost replication rep 192.168.56.102/32 md5
修改完配置需要重啟postgresql
# /usr/local/etc/rc.d/postgresql restart
2.複製資料至standby端
master端操作:# psql -U pgsql -d postgres -c "select pg_start_backup(‘backup‘)"
# cd /usr/local/pgsql
# tar zcf data.tgz data
# scp data.tgz 192.168.56.102:/usr/local/pgsql
# psql -U pgsql postgres -c "select pg_stop_backup()"
3.配置standby端
# /usr/local/etc/rc.d/postgresql stop
# cd /usr/local/pgsql
# rm -r data
# tar zxf data.tgz
# rm -r data/postmaster.pid data/pg_xlog/* data/backup_label
# vim data/postgresql.conf
hot_standby = on
--------刪除master端的三條配置語句------------
#listen_addresses = ‘*‘
#wal_level = ‘hot_standby‘
#max_wal_senders = 1
-------------------------------------------
# vim data/recovery.conf
standby_mode = ‘on‘
primary_conninfo = ‘host=192.168.56.101 port=5432 user=rep password=password‘
# vim data/pg_hba.conf
---------刪除master端的一條配置文句-----------
#host replication rep 192.168.56.102/32 md5
-------------------------------------------
# /usr/local/etc/rc.d/postgresql start
4.測試資料是否配置成功
master端# createdb -U pgsql mydb# psql -U pgsql mydbmydb=# create table foo(id bigint);mydb=# insert into foo select * from generate_series(1,100000);
mydb=# select * from pg_stat_replication;standby端# psql -U pgsql mydbmydb=# select count(*) from foo;
參考地址:
https://www.byvoid.com/zhs/blog/postgresql-wal-replication
http://blog.sciencenet.cn/home.php?mod=space&uid=419883&do=blog&id=537939
實現原理
主伺服器在接受到每個事務請求時,將資料改動用預寫記錄檔(WAL)記錄。具體而言,事務採用兩段提交(Two Phase Commit),即先將改動寫入預寫記錄檔,然後再實際改動資料庫。這樣可以保證預寫記錄檔的時間戳記永遠不落後於資料庫,即便是正在寫入時伺服器突然崩潰,重啟以後也可以依據預寫記錄檔將資料恢複,因為預寫記錄檔保留了比資料庫記錄中更新的版本。PostgreSQL的非同步複製解決方案正是利用了預寫記錄檔,將預寫記錄檔從主伺服器(Master Sever)傳輸到待命伺服器(Standby Server),然後在待命伺服器上回放(Replay)出預寫記錄檔中記錄改動,從而實現主從複製。PostgreSQL使用了兩種方式傳輸預寫記錄檔:存檔式(archive)和流式(streaming)。
存檔式複製的原理是主伺服器將預寫記錄檔主動拷貝到一個安全的位置(可以直接到待命伺服器,也可以是第三台伺服器),同時待命伺服器定期掃描這個位置,並將預寫記錄檔拷貝到待命伺服器端然後再回放。這樣即使主伺服器崩潰了,待命伺服器也可以從這個安全的位置擷取到一份完整的記錄,以確保任何資料不會丟失。而流式複製則簡化了這一個步驟,由主伺服器直接通過TCP協議向待命伺服器傳輸日誌,避免了兩次複製的開銷,有利於減小待命伺服器和主伺服器直接的資料延時。但當主伺服器崩潰時,未被傳輸到待命伺服器的日誌則會丟失,造成資料損失。PostgreSQL支援存檔式和流式兩種模式的混合,當兩種模式都開啟時,待命伺服器會定期檢查是否有存檔已經到達指定的位置,並回放日誌。一旦檢測到指定的位置沒有新的日誌,則會切換到流式模式試圖直接從網路傳輸日誌,接著再檢查存檔,不斷重複這一迴圈。
standby端啟動報錯:
May 22 05:43:51 93b postgres[634]: [3-1] FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000000000002 has already been removed
這是因為standby端啟動時,會從上文data.tgz記錄的wal位置到master端的data/pg_xlog目錄下尋找檔案,而master端的data/pg_xlog記錄檔,在standby端恢複資料的過程中已經被master端更新操作覆蓋替換掉,已找不到000000010000000000000002該檔案。
解決方案:重新去master端備份資料複製到standby重做,若測試環境下記得不要在完成配置standby端前,往master端更新資料。實際環境下未測試。
postgresql 流複製(streaming replication)