pgsql物理復制(pgsql 備庫的搭建以及角色互換,提升)


結構圖如下:

 

 

Postgresql早在9.0版本開始支持物理復制,也稱為流復制,通過從實例級復制出一個與主庫一模一樣的備庫。流復制同步方式有同步,異步兩種,如果主節點和備節點不是很忙,通常異步模式下備庫和主庫的延遲時間能夠控制在毫秒級。物理復制只能復制整個實例。

邏輯復制也成為選擇性復制,可以做到基於表級別的復制,選擇需要邏輯復制的表,而不是復制實例上的所有數據庫的表,10版本不支持內置的邏輯復制,通常使用第三方邏輯復制。

WAL日志記錄數據庫變化,格式為二級制格式,盡管流復制都是基於WAL,但是兩者本質不同,流復制是基於WAL物理復制,邏輯復制是基於WAL邏輯解析,將WAL解析成一種清晰,易於理解的格式。

 流復制和邏輯復制主要有以下差異:

  • 流復制是物理復制

核心原理是主庫將預寫入日志WAL日志發給備庫,備庫接收到WAL日志后進行重做。

邏輯復制核心是基於WAL,邏輯復制會根據預先設置好的規則解析WAL日志,將二進制文件解析成一定格式的邏輯變化信息(有點像oracle的物理備庫和邏輯備庫)。

 

  • 物理復制只能對實例級別,邏輯復制能夠對表級別進行復制
  • 物理復制能夠對DDL進行操作,邏輯復制DDL主庫不能復制到備庫
  • 物理復制必須大版本一致,邏輯復制支持跨大版本。

 

 

1.    物理復制

1.     異步流復制

環境情況:

主機

主機名

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'

 

2.     同步流復制

異步流復制可以轉換成同步流復制。

主庫配置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,主庫會向備庫傳送歸檔),讀操作不影響,需要手動的把歸檔同步到備庫,所以生產上,建議使用異步方式(一主一從架構)。

 

3.同步查看

查看延遲(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();

 

 

2.    流復制備升主庫

建議主備庫事先做個快照

 

首先判斷主備庫

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,表示切換完成(測試已切換完成)

 

 

查看新主庫:

 

 

測試新主庫可以進行讀寫操作,切換成功。

 

由於考錄到主庫宕機之后不可用,並沒有做主備互相切換,只做備庫升為主庫操作。

 

3.    流復制主備互換角色

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目錄的空間是否足夠大。

 

4. 流復制槽備庫高可用

很多時候在主庫產生xlog或者wal日志的時候,還沒有傳到從庫就被覆蓋了,為了保證xlog/wal日志不被覆蓋,postgres 就啟用流復制槽,讓沒有傳到從庫的xlog保存不被覆蓋,新的日志繼續產生。

 

配置流復制主備庫都需要進行參數設置。

 主庫設置以下,並需要重啟

     max_replication_slots = 4            # max number of replication slots

     wal_level = hot_standby 

 

  1. 在主庫上創建slot

select * from pg_create_physical_replication_slot('pg_5432');

 

 

 

 

查看是主庫否創建成功:

select * from pg_replication_slots ;

 

 

 

  1. 備庫recovery文件進行設置

 

vi /pgsql/pg_data/recovery.conf

 

 

primary_slot_name = 'pg_5432'

standby_mode = 'on'

recovery_target_timeline = 'latest'

primary_conninfo = 'user=rep password=rep host=192.168.10.41 port=5432

application_name=pg_5432 sslmode=disable sslcompression=1'  

 

 

 

其他的都一樣,就是多了一個primary_slot_name 配置,以及primary_conninfo里面需要加上application_name=流復制槽名稱

備庫進行重啟。

 

備庫重啟后再次查看主庫流復制槽信息:

select * from pg_replication_slots ;

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM