postgresql + pgpool 構建容災高可用集群(數據同步流復制/主備自動切換)


postgresql + pgpool 構建容災高可用集群(數據同步流復制/主備自動切換)

本篇主要是postgresql12 安裝配置部分。
pgpool-ii 配置在第二篇:pgpool-ii4.1.2 高可用集群[主備切換]配置部分

整個流程分為以下幾部分:

  1. postgresql-12 安裝
  2. postgresql-12 流復制配置以及驗證
  3. pgpoll-ii-4.1 安裝
  4. pgpool-ii-4.1 主備機器自動切換配置
  5. pgpoll-ii-4.1 配置說明
  6. 方案宕機效果測試

高可用(容災)效果:

先說說這套方案要達到的效果/解決的問題,目的不一致的/沒有想了解的可以不用往下看了.
解決三種宕機

  1. 某一個 postgresql 數據庫掛掉 (多台數據庫啟動后 其中一台作為主機,其余作為備機 構成一個數據庫集群);
    • 如果是主機primary,集群檢測到掛掉會通過配置的策略重新選一個備機standby切換為主機primary, 整個集群仍舊保證可用, 當原主機恢復服務后, 重新作為一個新備機standby,同步完數據后加入集群
    • 如果是備機standby,對整個集群無可見影響, 當備機恢復服務后,從主庫同步完數據后,恢復正常狀態加入集群;
  2. 某一台機器上的pgpool-ii 程序掛掉;
    • 監測每個pgpool-ii進程的狀態, 監測到掛掉之后,及時"切換"虛擬ip所在的主機以保證可用性(有些人叫IP漂移);
    • 整個集群始終對外提供一個唯一的,可用的虛擬IP 來提供訪問;
    • 監測每個主機postgresql數據庫的狀態, 以即使切換數據庫的主備角色;
  3. 某一台主機直接宕機;
    • 當pgpool-ii監測主機掛掉之后, 需要進行數據庫角色的切換和ip的切換兩個操作(如果需要)

方案結構:

基於兩台裝有postgresql數據庫的服務器,通過每台機器上的pgpool-ii程序來維護一個高可用體系, 從而保證能始終提供一個可用的IP地址,用於外界數據操作或者訪問.

發行版 ip hostname 補充說明
Cent OS7 10.242.111.204 master 安裝postgresql 12.1 + pgpool-ii 4.1並進行配置
Cent OS7 10.242.111.207 slave 安裝postgresql 12.1 + pgpool-ii 4.1並進行配置
/ 10.242.111.203 vip virtual ip, 通過一個虛擬的IP統一對外提供訪問
  • 2(n)台主機均安裝有postgresql 12 版本的數據庫和pgpool-ii 4.1 版本的中間件;
  • 2(n)個數據庫之間可以做到數據同步以(通過流復制來實現, 但同一時刻主機primary只有一台,其余作為備機standby)及身份切換;
  • pgpool-ii 是一個介於postgresql 服務器和postgresql數據庫之間的中間件, 提供了鏈接池(Connection Pooling),看門狗(WatchDog),復制,負載均衡,緩存等功能(具體的可以查看官方文檔);
  • 通過pgpool-ii 維護的虛擬ip, 向外界提供一個始終可用的訪問地址, 屏蔽掉具體的主機數據庫地址概念;
  • 通過pgpool-ii 程序來自動處理宕機后相關方案(后面有講)
  • 數據庫down之后需要通過pcp_attach_node將節點加入集群

流復制數據同步: 通過postgresql數據庫配置來實現

虛擬ip自動切換: 通過pgpool-ii 配置實現

數據庫主備角色切換: 通過pgpool-ii 監測機 + 執行 postgresql 中的promote命令來實現

postgreslq-12安裝(2台機器均安裝)

yum 在線安裝

#設置rpm源
curl -O  https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
rpm -ivh pgdg-redhat-repo-latest.noarch.rpm

#安裝(這里是版本為12的postgresql)
yum -y install postgresql12 postgresql12-server  -O

#如果后續發現連接不上,可以關閉防火牆
systemctl stop firewalld
systemctl disable firewalld

rpm離線安裝

# ftp下載rpm離線包
curl -O https://yum.postgresql.org/12/redhat/rhel-7-x86_64/postgresql12-12.3-1PGDG.rhel7.x86_64.rpm
curl -O https://yum.postgresql.org/12/redhat/rhel-7-x86_64/postgresql12-contrib-12.3-1PGDG.rhel7.x86_64.rpm
curl -O https://yum.postgresql.org/12/redhat/rhel-7-x86_64/postgresql12-libs-12.3-1PGDG.rhel7.x86_64.rpm
curl -O https://yum.postgresql.org/12/redhat/rhel-7-x86_64/postgresql12-server-12.3-1PGDG.rhel7.x86_64.rpm
#contrib 是安裝擴展的 沒有這個包就沒有 ossp-uuid的插件
#server 是數據庫的安裝文件
#libs 用來客戶端進行連接. 
#注意 如果是centos8 的話,修改為 rhel-8 進行下載就可以了.
# 上傳文件到服務器之后, 執行安裝命令
rpm -ivh postgresql*.rpm

執行完安裝之后(查看狀態可跳過, 直接進行數據庫初始化):

  • 會幫我們創建一個postgresql-12服務, 此時未進行數據庫初始化, 還無法訪問.
  • 會幫我們創建一個postgres/postgres 的用戶,密碼相同.

此時使用systemctl status postgreslq-12 查看服務狀態:

● postgresql-12.service - PostgreSQL 12 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-12.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: https://www.postgresql.org/docs/12/static/

我們可以找到默認配置文件地址: /usr/lib/systemd/system/postgresql-12.service

如果cat命令查看配置文件, 我們可以得到一些基礎信息:
數據庫數據目錄: Environment=PGDATA=/var/lib/pgsql/12/data/
postgresql安裝目錄: PGHOME=/usr/pgsql-12/

數據庫初始化

# 切換到postgres用戶
su - postgres
cd /usr/pgsql-12/bin
./initdb -D /var/lib/pgsql/12/data

**退回root用戶, 重啟postgrersql-12服務, 並設置開機自啟 **

systemctl enable  postgresql-12 && systemctl restart postgresql-12

**本機測試訪問 **

su - postgres
-bash-4.2$  psql
postgres=# (這里就可以開始寫查詢語句了)

**配置遠程訪問 **
修改數據目錄下配置文件: pg_hba.conf

vim /var/lib/pgsql/12/data/pg_hba.conf
# 在文件中添加:
host     all              all             0.0.0.0/0               md5

修改數據目錄下配置文件: postgresql.conf

vim /var/lib/pgsql/12/data/postgresql.conf
# 在文件中修改(此配置僅用於遠程訪問, 流復制后續還有額外配置):
listen_addresses = '*'
port = 5432
max_connections = 100 

修改完成重啟服務, 使用遠程命令或者遠程客戶端測試訪問即可

-- 使用遠程命令訪問
psql -h 10.242.111.204 -p 5432 -U postgres
-- 登陸成功可以執行操作
-- 如修改密碼 (引號中為新密碼)
postgres=# alter role postgres with password 'postgres';

postgresql-12 流復制(replication)/數據同步配置

流復制原理簡述

  1. 流復制大約是從pg9版本之后使用, 流復制其原理為:備庫不斷的從主庫同步相應的數據,並在備庫apply每個WAL record,這里的流復制每次傳輸單位是WAL日志的record。(關於預寫式日志WAL,是一種事務日志的實現)

    模型

  2. 圖中可以看到流復制中日志提交的大致流程為:

    1. 事務commit后,日志在主庫寫入wal日志,還需要根據配置的日志同步級別,等待從庫反饋的接收結果。
    2. 主庫通過日志傳輸進程將日志塊傳給從庫,從庫接收進程收到日志開始回放,最終保證主從數據一致性。
  3. 流復制同步級別
    通過在postgresql.conf配置synchronous_commit參數來設置同步級別

    synchronous_commit = off            # synchronization level;  
                                        # off, local, remote_write, or on 
    
    
    • remote_apply:事務commit或rollback時,等待其redo在primary、以及同步standby(s)已持久化,並且其redo在同步standby*(s)已apply。
    • on:事務commit或rollback時,等待其redo在primary、以及同步standby(s)已持久化。
    • remote_write:事務commit或rollback時,等待其redo在primary已持久化; 其redo在同步standby(s)已調用write接口(寫到 OS, 但是還沒有調用持久化接口如fsync)。
    • local:事務commit或rollback時,等待其redo在primary已持久化;
    • off:事務commit或rollback時,等待其redo在primary已寫入wal buffer,不需要等待其持久化;

配置時需要注意的點:

  1. postgresql-12版本不再支持通過recovery.conf的方式進行主備切換,如果數據目錄中存在recovery.conf,則數據庫無法啟動;
  2. 新增 recovery.signal 標識文件,表示數據庫處於 recovery 模式;
  3. 新增加 standby.signal 標識文件,表示數據庫處於 standby 模式(這個需要重點關注一下);
  4. 以前版本中 standby_mode 參數不再支持;
  5. recovery.conf文件取消, 合並到了postgresql.conf文件中;
  6. 配置中war_level存儲級別, postgresql-9.6以后有改變:
    等級 說明
    minimal 不能通過基礎備份和wal日志恢復數據庫
    replica 9.6新增,將之前版本的 archive 和 hot_standby合並, 該級別支持wal歸檔和復制
    logical 在replica級別的基礎上添加了支持邏輯解碼所需的信息

流復制配置過程

主庫(10.242.111.204)

  1. 創建一個賬戶repuser 用戶, 提供給備庫遠程訪問, 用來獲取流:
    su - postgres 
    -bash-4.2$ psql
    postgres=# create role repuser login replication encrypted password 'repuser';
    CREATE ROLE
    postgres=# \q
    
  2. 修改數據目錄下配置文件: pg_hba.conf
    vim /var/lib/pgsql/12/data/pg_hba.conf
    # 在文件中添加:
    host  replication     repuser        0.0.0.0/0             md5
    
  3. 修改數據目錄下配置文件: postgresql.conf
    vim /var/lib/pgsql/12/data/postgresql.conf
    # 在文件中修改(此配置僅用於遠程訪問, 流復制后續還有額外配置):
    listen_addresses = '*'
    port = 5432
    max_connections = 100       # 最大連接數,據說從機需要大於或等於該值
    
    # 控制是否等待wal日志buffer寫入磁盤再返回用戶事物狀態信息。同步流復制模式需要打開。
    synchronous_commit = on
    # *=all,意思是所有slave都被允許以同步方式連接到master,但同一時間只能有一台slave是同步模式。
    # 另外可以指定slave,將值設置為slave的application_name即可。
    synchronous_standby_names = '*'
    wal_level = replica
    max_wal_senders = 2   		#最多有2個流復制連接
    wal_keep_segments = 16  	
    wal_sender_timeout = 60s	#流復制超時時間
    

修改完成重啟postgresql-12服務systemctl restart postgresql-12

從庫(10.242.111.204)

  1. 關閉備庫postgresql服務
    systemctl stop postgresql-12
    
  2. 如果備庫機器上沒有 PGDATA(/var/lib/pgsql/12/data)目錄(恢復出故障數據目錄消失同樣操作)
    mkdir /var/lib/pgsql/12/data
    chmod 0700 data
    chown postgres.postgres data
    
  3. 把主庫整個備份到從庫
    其實后續的pgpool的主庫掛了, 從庫升級主庫之后, 主庫恢復為從庫的過程就是: 備份data目錄,然后重復這里的第2,3步驟
    # 切換到postgres用戶,否則備份的文件屬主為root, 導致啟動出錯
    su – postgres
    pg_basebackup -h 10.242.111.204 -p 5432 -U repuser -Fp -Xs -Pv -R -D /var/lib/pgsql/12/data
    # -h 的ip是當前的主庫, -U 就是前面個船艦的用來復制的那個用戶
    
    額外需要注意的是:
    • 如果主庫的pg_hba.conf中配置的策略為trust, 這里不需要口令, 如果為md5模式,需要輸你創建用戶時的那個密碼;
    • 這里 -R 參數一定要加, 拷貝完在$PGDATA目錄下生成standby.signal標志文件(用於表示此庫為備庫);
    • 使用命令同步完之后, 在data目錄下會自動生成postgresql.auto.conf文件中, 優先級是大於postgresql.conf的;
    • 這里面的參數請嚴格參照官網釋義;
  4. 啟動備庫postgresql-12 服務
    systemctl restart postgresql-12
    

流復制驗證

使用命令或者遠程客戶端工具登入postgresql主(primary)數據庫

# 切換垂直顯示
postgres=# \x
Expanded display is on.
# 查詢備機連接
postgres=# select * from pg_stat_replication;
    -[ RECORD 1 ]----+------------------------------
    pid              | 27132
    usesysid         | 16384
    usename          | repuser
    application_name | walreceiver
    client_addr      | 10.242.111.207
    client_hostname  |
    client_port      | 34726
    backend_start    | 2020-06-19 16:23:01.309172+08
    backend_xmin     |
    state            | streaming
    sent_lsn         | 0/11000148
    write_lsn        | 0/11000148
    flush_lsn        | 0/11000148
    replay_lsn       | 0/11000148
    write_lag        |
    flush_lag        |
    replay_lag       |
    sync_priority    | 1
    sync_state       | sync
    reply_time       | 2020-06-19 18:39:43.346062+08
# 可以發現207的那台備機已經連接上, 並且使用的是 sync 同步模式(async 為異步)
# 此時可以在主庫上創建數據庫/表/添加數據, 然后去備庫上查詢 以顯示效果, 如:
postgres=# create database test_204;
postgres=# \test_204
postgres=# create table test_table(name text);
postgres=# insert into test_table(name) values ('china');

# 補充基礎查詢命令
# \list 列出可用數據庫
# \db_name 選擇數據庫
# \dt 查詢關系表

至此, 流復制(數據同步)策略完成.

postgresql 主從切換(primary->standby)

  1. 主數據庫是讀寫的,備數據庫是只讀的。
  2. 使用/usr/pgsql-12/bin/pg_controldata /var/lib/pgsql/12/data/ 可以查看數據庫運行狀態
    • Database cluster state: in production (主庫為運行中)
    • Database cluster state: in archive recovery (從庫為正在歸檔回復)
  3. 當主庫primary 出現故障, 我們需要將從庫standby提升為主庫primary;
    • pg12版本以前的切換方式有兩種:
      • pg_ctl 方式: 在備庫主機執行 pg_ctl promote shell 腳本
      • 觸發器文件方式: 備庫配置 recovery.conf 文件的 trigger_file 參數,之后在備庫主機上創建觸發器文件
    • pg12開始新增了一個pg_promote()函數, 支持知用promote指令進行切換
    • pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60)
      • wait: 表示是否等待備庫的 promotion 完成或者 wait_seconds 秒之后返回成功,默認值為 true
      • wait_seconds: 等待時間,單位秒,默認 6
  4. 切換舉例
    # 關閉主庫primary
    systemctl stop postgresql-12
    # 從庫上執行切換
    # 第一種
    /usr/pgsql-12/bin/pg_ctl promote -D /var/lib/pgsql/12/data
    # 第三種
    su postgres
    psql
    postgres=# select pg_promote(true,60);
    # 此時從庫會提升為主庫接管集群中的讀寫操作
    

pgpool-ii 中默認的 failover_command 切換數據庫主備角色腳本, 是通過pg_ctl promote 來實現的

后續pgpool操作見下一篇文章

參考資料:

  1. 流復制
  2. 容災測試
  3. pg_basebackup介紹


免責聲明!

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



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