結構圖以下:sql
Postgresql早在9.0版本開始支持物理複製,也稱爲流複製,經過從實例級複製出一個與主庫如出一轍的備庫。流複製同步方式有同步,異步兩種,若是主節點和備節點不是很忙,一般異步模式下備庫和主庫的延遲時間可以控制在毫秒級。物理複製只能複製整個實例。數據庫
邏輯複製也成爲選擇性複製,能夠作到基於表級別的複製,選擇須要邏輯複製的表,而不是複製實例上的全部數據庫的表,10版本不支持內置的邏輯複製,一般使用第三方邏輯複製。架構
WAL日誌記錄數據庫變化,格式爲二級制格式,儘管流複製都是基於WAL,可是二者本質不一樣,流複製是基於WAL物理複製,邏輯複製是基於WAL邏輯解析,將WAL解析成一種清晰,易於理解的格式。oracle
流複製和邏輯複製主要有如下差別:app
核心原理是主庫將預寫入日誌WAL日誌發給備庫,備庫接收到WAL日誌後進行重作。異步
邏輯複製核心是基於WAL,邏輯複製會根據預先設置好的規則解析WAL日誌,將二進制文件解析成必定格式的邏輯變化信息(有點像oracle的物理備庫和邏輯備庫)。工具
環境狀況:post
主機性能 |
主機名測試 |
IP |
操做系統 |
Postgresql版本 |
master |
10pg1 |
192.168.10.41 |
Centos6.9 |
PostgreSQL 10.8 |
slave |
10pg2 |
192.168.10.51 |
Centos6.9 |
PostgreSQL 10.8 |
這種環境的部署包括兩種方式:
① 數據文件拷貝的方式
② pg_basebackup方式部署
本次將介紹pg_basebackup方式部署。
1. 兩臺都要安裝postgresql
2. 主庫建立建立Replication用戶(如下都是主庫操做)
CREATE ROLE rep login replication password 'rep';
修改master的pg_hba.conf文件:
修改Master庫數據庫配置(postgresql.conf)
要使用流複製,必定要把wal_level = hot_standby設置成hot_standby,其中要開啓歸檔模式
wal_level = hot_standby # 這個是設置主爲wal的主機
max_wal_senders = 5 # 這個設置了能夠最多有幾個流複製鏈接
wal_keep_segments = 128 # 設置流複製保留的最多的xlog數目
wal_sender_timeout = 60s # 設置流複製主機發送數據的超時時間
max_connections = 100 # 這個設置要注意下,從庫的max_connections必需要大於主庫的
配置完後重啓主庫。
3. 如下都是備庫操做
修改master的pg_hba.conf文件:
host all all 192.168.10.0/24 md5
host replication rep 192.168.10.41/24 md5
host replication rep 192.168.10.51/24 md5
使用pg_basebackup建備庫
pg_basebackup -h 192.168.10.41 -Urep -Ft -Pv -Xf -z -Z5 -p 5432 -D /backup/20190629/
中止備庫進行恢復操做:
cd /pgsql/
mv pg_data/ pg_databak
mkdir -p /pgsql/pg_data
cd /pgsql/
chmod 700 pg_data
chown -R postgres:postgres /pgsql/
tar -zxvf /backup/20190629/base.tar.gz -C /pgsql/pg_data/
拷貝主庫的recovery.conf文件到備庫(主庫執行)
scp /usr/local/pgsql/share/recovery.conf.sample 192.168.10.51:/pgsql/pg_data/recovery.conf
備庫修改recovery.conf
standby_mode=on
primary_conninfo = 'user=rep password=rep host=192.168.10.41 port=5432'
recovery_target_timeline = 'latest'
啓動備庫後,會報錯,接下來修改postgresql.conf
vi postgresql.conf
max_connections = 200 # 通常查多於寫的應用從庫的最大鏈接數要比較大
hot_standby = on # 說明這臺機器不只僅是用於數據歸檔,也用於數據查詢
max_standby_streaming_delay = 30s # 數據流備份的最大延遲時間
wal_receiver_status_interval = 10s # 多久向主報告一次從的狀態,固然從每次數據複製都會向主報告狀態,這裏只是設置最長的間隔時間
hot_standby_feedback = on # 若是有錯誤的數據複製,是否向主進行反饋
測試:
主庫操做:
備庫:
同步正常。
備庫只能執行查詢,與Oracle dg相似,且slave停掉後,主庫可以正常的運行,wal日誌不能傳向遠端。
啓動後,把主庫的歸檔日誌傳向備庫,備庫繼續應用日誌(不像ORACLE須要手動應用日誌)。
備庫停庫後主庫delete操做:
備庫啓動後,主庫傳完歸檔日誌操做:
主備庫一致性查詢操做:
主備一致,且主庫執行同步查詢:
select pid,state, client_addr,sync_priority,sync_state from pg_stat_replication;
select * from pg_stat_replication ;
檢查數據庫主從複製進度:
查看流複製的信息可使用主庫上的視圖
select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
查看備庫落後主庫多少字節
select pg_xlog_location_diff(pg_current_xlog_location(),replay_location)/1024/1024 as MB from pg_stat_replication;
select pg_xlog_location_diff(pg_current_xlog_location(),replay_location)/1024/1024/1024 as GB from pg_stat_replication;
級聯複製
select pg_xlog_location_diff(pg_last_xlog_replay_location(),replay_location)/1024/1024/1024 as GB from pg_stat_replication;
查看備庫由於衝突而被取消的SQL:
select * from pg_stat_database_conflicts;
顯示備庫詳細信息:pg_controldata
備庫wal 日誌清理:
因爲個人備庫WAL日誌存在/pgsql/pg_data/pg_wal目錄。
vi /pgsql/pg_data/recovery.conf
archive_cleanup_command = 'pg_archivecleanup /pgsql/pg_data/pg_wal %r'
異步流複製能夠轉換成同步流複製。
主庫配置postgresql.conf:
synchronous_commit = on
synchronous_standby_names = 'standby1' --備庫設置節點別名
備庫配置recovery.conf
primary_conninfo = 'application_name=standby1 user=rep password=rep host=192.168.10.41 port=5432 sslmode=disable sslcompression=1'
recovery_target_timeline = 'latest'
配置完後重啓主備庫。
查看同步方式:
select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
同步複製環境中,因爲主庫提交事務至少須要一個備庫接收WAL,並返回確認信息後主庫才向客戶端返回成功,一方面保證了數據的完整性,另外一方面對於一主一備的同步環境變現的陷阱是,若是備庫宕機,主庫上的寫操做即處於等待狀態(這點跟ORACLE不同,Oracle 有gap,主庫會向備庫傳送歸檔),讀操做不影響,須要手動的把歸檔同步到備庫,因此生產上,建議使用異步方式(一主一從架構)。
查看延遲(wal延遲時間衡量):
select * from pg_stat_replication ;
經過WAL日誌應用延遲量衡量:
select
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn)) as sent_delay,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn)) as write_delay,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), flush_lsn)) as flush_delay,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) as replay_delay
from pg_stat_replication;
select * from pg_stat_wal_receiver;
查看恢復進程是否處於恢復模式:
SELECT PG_IS_IN_RECOVERY();
顯示備庫最近接收的WAL日誌位置:
select pg_last_wal_receive_lsn();
顯示備庫最近應用的WAL日誌位置:
select pg_last_wal_replay_lsn();
顯示備庫最近事務的應用時間:
select pg_last_xact_replay_timestamp();
顯示主庫WAL當前寫入位置:
select pg_current_wal_lsn();
建議主備庫事先作個快照
首先判斷主備庫
ps -ef | grep "wal"
能夠查看有
主
備:
或者查看如下SQL 有內容的爲主庫,沒有內容的爲從庫。
select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
或者查看
select pg_is_in_recovery(); -- t爲備 f爲主庫
pg_controldata 備庫Database cluster state參數 爲 in archive recovery模式;主庫爲in production 模式。
9.0以前切換須要文件出發方式,9.1開始,支持pg_ctlpromote出發方式,相比文件出發方式更方便。
Promote命令發出後,運行中的備庫將中止恢復模式,並切換成讀寫模式的主庫。步驟以下:
1.關閉主庫,建議使用-m fast模式關閉。
pg_ctl stop -D /pgsql/pg_data/ -m fast
2.備庫執行命令激活備庫
pg_ctl promote -D /pgsql/pg_data
查看備庫原備庫recovery.conf 變成recovery.done,表示切換完成(測試已切換完成)
查看新主庫:
測試新主庫能夠進行讀寫操做,切換成功。
因爲考錄到主庫宕機以後不可用,並無作主備互相切換,只作備庫升爲主庫操做。
Pg_rewind 是pgsql一個很是好的數據同步工具,若是主備互相切換的時候忘記關閉主庫,除了從新搭建備庫外,就會用到提供的pg_rewind工具。
pg_rewind:
主備庫設置參數 wal_log_hints = on ,若是數據庫初始化的時候是 --data-checksums選項能夠不用設置此參數,因爲--data-checksums會在數據塊上進行檢測,發現I/O錯誤,開啓後後性能損失。
設置號wal_log_hints = on 後,進行重啓生效。
① 激活備庫
參數設置好後,備庫提高爲主庫
pg_ctl promote -D /pgsql/pg_data
提高成功。
② 主庫轉換爲備庫
關閉原來的主庫。
pg_ctl stop -D /pgsql/pg_data/ -m fast
使用pg_rewind 工具增量同步10pg2到10pg1的數據。
pg_rewind --target-pgdata=/pgsql/pg_data/ --source-server='host=192.168.10.51 port=5432 user=postgres password=postgres dbname=postgres' -P
mv recovery.done recovery.conf
vi recovery.conf
把主庫信息修改一下
vi postgresql.conf
修改監聽地址。
後啓動成功後
pg_ctl start -D /pgsql/pg_data/
查看日誌有報錯
把51的日誌cp到41 wal日誌目錄(因爲我主庫有新的數據生成)
新備庫立馬同步正常。
延遲設置:
若是備庫不須要實時同步,設置此參數:
vi recovery.conf
recovery_min_apply_delay = 30s
默認是0 毫秒,支持ms,s,min,h,d(毫秒,秒,分鐘,小時,天),注意參數須要重啓生效;
若是設置時間過大,須要注意wal目錄的空間是否足夠大。