pgsql主備搭建及切換


二、主從搭建

2.1測試目標

測試postgresql主從搭建安裝過程

2.2環境准備

實例級別的復制

流復制主庫可讀寫,但從庫只允許查詢不允許寫人, 而邏輯復制的從庫可讀寫

 

流復制實驗環境

主機

主機名

Ip地址

操作系統

Postgresql版本

主節點

pgsql

192.168.231.131

Redhat7.2

PostgreSQL10

備節點

pgstandby

192.168.231.132

Redhat7.2

PostgreSQL10

 

在 pgsql 和 pgstandby上創建操作系統用戶和相關目錄,如下所示:

# groupadd pgsql

# useradd pgsql -g pgsql

# passwd pgsql

# mkdir -p /database/pg10/pg_root

# mkdir -p /database/pg10/pg_tbs

# chown -R pgsql:pgsql /database/pg10

 

/database/pg10/pg_root 目錄存儲數據庫系統數據文件,

/database/pg10/pg_tbs 存儲用戶自定義表空間文件。

設置 postgres 操作系統用戶環境變量,

/home/postgres/.bash _profile 文件添加以下內容:

export PGPORT=5432

export PGUSER=pgsql

export PGDATA=/database/pg10/pg_root

export LANG=en_US.utf8

export PGHOME=/usr/pgsql-10

export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib

export PATH=$PGHOME/bin:$PATH:.

export MANPATH=$PGHOME/share/man:$MANPATH

 

2.3初始化數據庫

[pgsql@pgstandby ~]$ initdb -D /database/pg10/pg_root -E UTF8 --locale=C -U pgsql -W   (初始化創建數據庫實例)

-A  authmethod這個選項聲明本地用戶在 pg_hba.conf 里面使用的認證方法。除非你相信所有本地用戶,否則不要使用 trust(缺省)。

-D  directory這個選項聲明數據庫集群應該存放在哪個目錄。這是 initdb 需要的唯一信息,但是你可以通過設置 PGDATA 環境變量來避免鍵入,這樣做可能方便一些,因為稍后數據庫服務器(postgres)可以通過同一個變量找到數據庫目錄。

-E encoding 選擇模板數據庫的編碼方式。這將是你以后創建的數據庫的缺省編碼方式,除非你創建數據庫時覆蓋了它。缺省是從區域設置中獲得的,如果沒有區域設置,就是 SQL_ASCII 。

--locale=locale 為數據庫集群設置缺省的區域。如果沒有聲明這個選項,那么區域是從 initdb 運行的環境中繼承過來的。

-U username 選擇數據庫超級用戶的用戶名。缺省是運行 initdb 的用戶的有效用戶。超級用戶的名字是什么並不重要,但是可以選擇習慣的名字 postgres ,即使操作系統的用戶名字不一樣也沒關系。

-W 令 initdb 提示輸入數據庫超級用戶的口令。如果你不准備使用口令認證,這個東西並不重要。否則你將不能使用口令認證,直到你設置了口令。

--pwfile=filename令 initdb 從一個文件里讀取數據庫超級用戶的口令。該文件的第一行將被當作口令使用。

其它不常用的參數還有:

-d 從初始化后端打印調試輸出以及一些其它的一些普通用戶不太感興趣的信息。初始化后端是 initdb 用於創建系統表的程序。這個選項生成大量非常枯燥的輸出。

-L directory 告訴 initdb 到哪里找初始化數據庫所需要的輸入文件。通常是不必要的。如果需要你明確聲明的話,程序會提示你輸入。

-n 缺省時,當 initdb 發現一些錯誤妨礙它完成創建數據庫集群的工作時,它將在檢測到不能結束工作之前將其創建的所有文件刪除。這個選項禁止任何清理動作,因而對調試很有用。

 

 

之后配置 $PGDATA/postgresql.conf 設置以下參數:

listen_addresses = ‘*’             

wal_level = replica # minimal, replica, or logical

archive_mode = on         # enables archiving; off, on, or always

archive_command = ’/ bin/date’   # command to use to archive a logfile segment

max_wal_senders = 10 # max number of walsender processes

wal_keep_segments = 512     # in logfile segment s, 16MB each; 0 disables

hot_standby = on

 

listen_addresses參數指定哪些ip可以訪問,’*’代表所有ip可以訪問數據庫。

Wal_level參數控制WAL日志信息的輸出級別,有minimal、replica、logical三種模式,minimal記錄的WAL日志信息最少,除了記錄數據庫異常關閉需要恢復時的WAL信息外,其他操作信息都不記錄;replica記錄的WAL信息比minimal信息多些,會記錄支持WAL歸檔、復制和備庫中啟用只讀查詢等操作所需的WAL信息;logical記錄的WAL日志信息最多,包含了支持邏輯解析(10版本的新特性,邏輯復制使用這種模式,本章后面會介紹)所需的WAL;replica模式記錄的WAL信息包含了minimal記錄的信息,logical模式記錄的WAL信息包含了replica記錄的信息,此參數默認值為replica,調整此參數需重啟數據庫生效,開啟流復制至少需要設置此參數為replica級別

 

Archive_mode參數控制是否啟用歸檔,off表示不啟用歸檔,on表示啟用歸檔並使用archive_command參數的配置命令將WAL日志歸檔到歸檔存儲上,此參數設置后需重啟數據庫生效,這里通常設置成on。

 

archive_command參數設置WAL歸檔命令,可以將WAL歸檔到本機目錄,也可以歸檔到遠程其他主機上,由於流復制的配置並不一定需要依賴配置歸檔命令,我們將歸檔命令暫且設置成偽歸檔命令/bin/date,后期如果需要打開歸檔直接配置歸檔命令即可。

 

max_wal_senders參數控制主庫上的最大WAL發送進程數,通過pg_base_backup命令在主庫上做基准備份時也會消耗WAL進程,此參數設置不能比max_connections參數值高,默認值為10,一個流復制備庫通常只需要消耗流復制主庫一個WAL發送進程。

 

wal_keep_segments參數設置主庫pg_wal目錄保留的最小WAL日志文件數,以便備庫落后主庫時可以通過主庫保留的WAL進行追回,這個參數設置得越大,理論上備庫在異常斷開時追平主庫的機率越大,如果歸檔存儲空間充足,建議將此參數配置得大些,由於默認情況下每個WAL文件為16MB(編譯時可通過--with-walsegsize參數設置WAL文件大小),因此pg_wal目錄大概占用空間為wal_keep_segments參數值×16MB,這里為512×16MB=8GB,實際情況下pg_wal目錄下的WAL文件數會比此參數的值稍大。

 

hot_standby參數控制數據庫恢復過程中是否啟用讀操作,這個參數通常用在流復制備庫,開啟此參數后流復制備庫支持只讀SQL,但備庫不支持寫操作,主庫上也設置此參數為on。

 

以上是流復制配置過程中主要的 postgresqI. conf參數,其他參數沒有列出,主庫和備庫的 postgresqI. conf配置建議完全一致。

配置主庫的pg_hba.conf文件,添加以下內容:

host    replication     repuser         192.168.231.131/24      md5

host    replication     repuser         192.168.231.132/24      md5

 

意思為允許repuser用戶從外部地址通過密碼連接任何數據庫,配置兩個信息是因為以后方便主備切換。

2.4 異步流復制

2.4.1拷貝數據文件形式部署流復制(方案一)

#  chown -R pgsql:pgsql /var/run/postgresql/     --若開啟postgresql數據庫失敗,報/var/run/postgresql/權限不足的情況下,請賦權

drwxr-xr-x.  2 pgsql          pgsql            80 Aug  9 11:03 postgresql

 

$  pg ctl start

使用超級用戶pgsql登錄到數據庫創建流復制用戶 repuser,流復制用戶需要有 REPLICATION 權限和 LOGIN 權限

[pgsql@pgsql ~]$ psql postgres

psql (10.9)

Type "help" for help.

postgres=# create user repuser replication login connection limit 5 encrypted password 'hufj123';

CREATE ROLE

postgres=# SELECT pg_start_backup('frans_bk1');

 pg_start_backup

-----------------

 0/2000028

(1 row)

pg_ start_ backup()函數在主庫上發起一個在線備份

[pgsql@pgsql pg10]$ tar czvf pg_root.tar.gz pg_root --exclude=pg_root/pg_wal    --主庫將$PGDATA路徑下的東西進行備份,將pg_wal排除在外是因為,備庫會同步這些日志

[pgsql@pgsql pg10]$ scp pg_root.tar.gz pgsql@192.168.231.132:/database/pg10/   --將備份好的tar文件傳到備庫上去

備庫操作:

[pgsql@pgstandby pg10]$ tar xvf pg_root.tar.gz                               --備庫進行解壓,在$PGDATA目錄下

主庫操作:

[pgsql@pgsql pg10]$ psql postgres

postgres=# SELECT pg_stop_backup();                                       --主庫關閉備份,其實在備份好tar文件之后也可以進行關閉備份

NOTICE:  pg_stop_backup complete, all required WAL segments have been archived

 pg_stop_backup

----------------

 0/2000130

(1 row)

 

[pgsql@pgstandby pg_root]$ cp /usr/pgsql-10/share/recovery.conf.sample  $PGDATA/recovery.conf  --備庫拷貝一份recovery.conf文件

[pgsql@pgstandby pg_root]$ vi recovery.conf

recovery_target_timeline = 'latest'                      

standby_mode = on

primary_conninfo = 'host=192.168.231.131 port=5432 user=repuser'

 

[pgsql@pgstandby ~]$ touch .pgpass            --在家目錄下面創建.pgpass文件,目的是在連接主庫的時候不需要輸入密碼

[pgsql@pgstandby ~]$ chmod 0600 .pgpass       --注意賦予0600權限

[pgsql@pgstandby ~]$ cat .pgpass

192.168.231.132:5432:replication:repuser:hufj123

192.168.231.131:5432:replication:repuser:hufj123

 

不配置 .pgpass文件則警告日志顯示下面信息

2019-08-05 11:37:42.556 CST [76967] FATAL:  could not connect to the primary ser

ver: fe_sendauth: no password supplied

 

遇到錯誤查看日志 $PGDATA/log/路徑的日志。

如果此步沒報錯,並且主庫上可以查看到 WAL 發送進程,同時備庫上可以看到 WAL 接收進程說明流復制配置成功,查看主庫上的 WAL 發送進程, 如下所示:

 

[pgsql@pgsql ~]$ ps -ef|grep wal

pgsql     35001  34996  0 22:27 ?        00:00:00 postgres: wal writer process

pgsql     35006  34996  0 22:27 ?        00:00:00 postgres: wal sender process repuser 192.168.231.132(55152) streaming 0/7000098

pgsql     35008  34790  0 22:27 pts/1    00:00:00 grep --color=auto wal

 

查看備庫上的 WAL 接收進程,如下所示:

 

[pgsql@pgstandby ~]$ ps -ef|grep wal

pgsql     59336  59310  1 22:27 ?        00:00:00 postgres: wal receiver process   streaming 0/70000D0

pgsql     59347  58742  0 22:27 pts/3    00:00:00 grep --color=auto wal

接着在主庫上創建一個測試表並插入數據,如下所示:

postgres=# create table test_sr(id int4);

CREATE TABLE

postgres=# insert into test_sr values(1);

INSERT 0 1

備庫上驗證數據是否同步:

 

postgres=# select * from test_sr;

 id

----

  1

(1 row)

 

2.4.2 pg_basebackup(實例級的備份) 方式部署流復制(方案二)

 

將備庫停庫,刪除數據庫,進行測試

[pgsql@pgstandby ~]$ pg_ctl stop

waiting for server to shut down.... done

server stopped

[pgsql@pgstandby ~]$ rm -rf /database/pg10/pg_root/*

[pgsql@pgstandby ~]$ rm -rf /database/pg10/pg_tbs/*

[pgsql@pgstandby ~]$ pg_basebackup -D /database/pg10/pg_root -Fp -Xs -v -P -h 192.168.231.131 -p 5432 -U repuser

 

 

-D 參數表示指定備節點用來接收主庫數據的目標路徑,這里和主庫保持一致,依然是/database/pg10/pg_root目錄。

-F參數指定pg_basebackup命令生成的備份數據格式,支持兩種格式,p(plain)格式和t(tar)格式,p(plain)格式是指生成的備份數據和主庫上的數據文件布局一樣,也就是說類似於操作系統命令將數據庫$PGDATA系統數據文件、表空間文件完全拷貝到備節點;t(tar)格式是指將備份文件打個tar包並存儲在指定目錄里,系統文件被打包成base.tar,其他表空間文件被打包成oid.tar,其中OID為表空間的OID。

-X參數設置在備份的過程中產生的WAL日志包含在備份中的方式,有兩種可選方式,f(fetch)和s(stream),f(fetch)是指WAL日志在基准備份完成后被傳送到備節點,這時主庫上的wal_keep_segments參數需要設置得較大,以免備份過程中產生的WAL還沒發送到備節點之前被主庫覆蓋掉,如果出現這種情況創建基准備份將會失敗,f(fetch)方式下主庫將會啟動一個基准備份WAL發送進程;s(stream)方式中主庫上除了啟動一個基准備份WAL發送進程外還會額外啟動一個WAL發送進程用於發送主庫產生的WAL增量日志流,這種方式避免了f(fetch)方式過程中主庫的WAL被覆蓋掉的情況,生產環境流復制部署推薦這種方式,特別是比較繁忙的庫或者是大庫。

-v參數表示啟用verbose模式,命令執行過程中打印出各階段的日志,建議啟用此參數,了解命令執行到哪個階段。

-P參數顯示數據文件、表空間文件近似傳輸百分比,由於執行pg_basebackup命令過程中主庫數據文件會變化,因此這只是一個估算值;建議啟用此選項,了解數據復制的進度。

 

[pgsql@pgstandby~]$cp /usr/pgsql-10/share/recovery.conf.sample $PGDATA/recovery.conf    --此文件在pghome/share/下面

[pgsql@pgstandby ~]$ vi /database/pg10/pg_root/recovery.conf

recovery_target_timeline = 'latest'                      

standby_mode = on

primary_conninfo = 'host=192.168.231.131 port=5432 user=repuser'

 

[pgsql@pgstandby ~]$ pg_ctl start

 

postgres=# select usename,application_name,client_addr,sync_state from pg_stat_replication;     --主庫查詢查看同步模式

 usename | application_name |   client_addr   | sync_state

---------+------------------+-----------------+------------

 repuser | walreceiver      | 192.168.231.132 | async

 

2.5 同步流復制

異步流復制指主庫上提交事務時不需要等待備庫接收井寫入WAL日志時便返回成功,如果主庫異常看機,主庫上已提交的事務可能還沒來得及發送給備庫,就會造成備庫數據丟失,備庫丟失的數據量和WAL復制延遲有關,WAL復制延遲越大,備庫上丟失的數據量越大。同步流復制在主庫上提交事務時需等待備庫接收並WAL日志,當主庫至少收到一個備庫發回的確認信息時便返回成功,同步流復制確保了至少一個備庫收到了主庫發送的WAL日志,一方面保障了數據的完整性,另一方面增加了事務響應時間,因此同步流復制主庫的吞吐量相比異步流復制主庫吞吐量低。

 

配置同步流復制

備庫recovery.conf配置文件設置以下參數,如下所示:

primary_conninfo=’host=192.168.231.131 port=5432 user=repuser application_name=node2’

 

primary_conninfo參數添加application_name選項,application_name選項指定備節點的別名,主庫postgresql.conf的synchronous_standby_names參數可引用備庫application_name選項設置的值,這里設置成node2。

主庫上postgresql.conf配置文件設置以下參數,其他參數和異步流復制配置一致。

synchronous_commit = on或remote_apply     --建議設置為on,remote_apply是備庫應用后才返回信息

synchronous_standby_narnes = ’node2’

 

wal_level配置也和異步流復制配置一致,設置成replica或logical即可。

重啟主庫與備庫查詢復制狀態為sync

[pgsql@pgsql pg_root]$ psql postgres

psql (10.9)

Type "help" for help.

 

postgres=# select usename,application_name ,client_addr ,sync_state from pg_stat_replication;

 usename | application_name |   client_addr   | sync_state

---------+------------------+-----------------+------------

 repuser | node2            | 192.168.231.132 | sync

(1 row)

 

postgres=#

 

流復制監控

pg_stat_replication視圖

application_name:連接WAL發送進程的應用別名,此參數顯示值為備庫recovery.conf配置文件中primary_conninfo參數application_name選項的值。

client_addr:連接到WAL發送進程的客戶端IP地址,也就是備庫的IP。

backend_start:WAL發送進程的啟動時間。

state:顯示WAL發送進程的狀態,startup表示WAL進程在啟動過程中;catchup表示備庫正在追趕主庫;streaming表示備庫已經追趕上了主庫,並且主庫向備庫發送WAL日志流,這個狀態是流復制的常規狀態;backup表示通過pg_basebackup正在進行備份;stopping表示WAL發送進程正在關閉。

sent_lsn:WAL發送進程最近發送的WAL日志位置。

write_lsn:備庫最近寫人的WAL日志位置,這時WAL日志流還在操作系統緩存中,還沒寫人備庫WAL日志文件。

flush_lsn:備庫最近寫人的WAL日志位置,這時WAL日志流已寫入備庫WAL日志文件。

replay_lsn:備庫最近應用的WAL日志位置。

write_lag:主庫上WAL日志落盤后等待備庫接收WAL日志(這時WAL日志流還沒寫人備庫WAL日志文件,還在操作系統緩存中)並返回確認信息的時間。

flush_lag:主庫上WAL日志落盤后等待備庫接收WAL日志(這時WAL日志流已寫人備庫WAL日志文件,但還沒有應用WAL日志)並返回確認信息的時間。

replay_lag:主庫上WAL日志落盤后等待備庫接收WAL日志(這時WAL日志流已寫入備庫WAL日志文件,並且己應用WAL日志)並返回確認信息的時間。

sync_priority:基於優先級的模式中備庫被選中成為同步備庫的優先級,對於基於quorum的選舉模式此字段則無影響。

sync_state:同步狀態,有以下狀態值,async表示備庫為異步同步模式;potential表示備庫當前為異步同步模式,如果當前的同步備庫岩機,異步備庫可升級成為同步備庫;sync表示當前備庫為同步模式;quorum表示備庫為quorum standbys的候選。

 

pg_stat_wal_receiver顯示wal發送進程的詳細信息

主要字段信息

pid:WAL接收進程的進程號。

status:WAL接收進程的狀態。

Receive_start_lsn:WAL接收進程啟動后使用的第一個WAL日志位置。

Received_lsn:最近接收井寫人WAL日志文件的WAL位置。

last_msg_send_time:備庫接收到發送進程最后一個消息后,向主庫發回確認消息的發送時間。

last_msg_receipt_time:備庫接收到發送進程最后一個消息的接收時間。

conninfo:WAL接收進程使用的連接串,連接信息由備庫$PGDATA目錄的recovery.conf配置文件的primary_conninfo參數配置。

三、流復制主備切換

3.1判斷主備角色
方式一:ps -ef|grep wal 查看wal進程描述信息,判斷主備

方式二: 主庫查詢SELECT  *  from  pg_stat_replication,備庫查此視圖是無記錄的; 備庫查詢select  *  from  pg_stat_wal_receiver,同主庫查此視圖無記錄。

方式三:SELECT pg_is_in_recovery(); 返回t說明為備庫,返回f為主庫。

方式四:通過pg_controldata查看數據庫控制信息;通過Database cluster state信息判斷;結果顯示 in production 為主庫;結果顯示 in archive recovery為備庫。

方式五:通過recover.conf配置文件查看。

 

3.2 判斷主備是否正常

(1) 查看主備庫的進程

主庫發送進程:

[pgsql@pgsql ~]$ ps -ef|grep wal

pgsql     35001  34996  0 22:27 ?        00:00:00 postgres: wal writer process

pgsql     35006  34996  0 22:27 ?        00:00:00 postgres: wal sender process repuser 192.168.231.132(55152) streaming 0/7000098

pgsql     35008  34790  0 22:27 pts/1    00:00:00 grep --color=auto wal

備庫為接收進程:

[pgsql@pgstandby ~]$ ps -ef|grep wal

pgsql     59336  59310  1 22:27 ?        00:00:00 postgres: wal receiver process   streaming 0/70000D0

pgsql     59347  58742  0 22:27 pts/3    00:00:00 grep --color=auto wal

(2) 主庫插入數據,觀察備庫是否能收到數據。

(3) 主庫查詢復制狀態參數,是否正常。

[pgsql@pgsql pg_root]$ psql postgres

psql (10.9)

Type "help" for help.

 

postgres=# select usename,application_name ,client_addr ,sync_state from pg_stat_replication;

 usename | application_name |   client_addr   | sync_state

---------+------------------+-----------------+------------

 repuser | node2            | 192.168.231.132 | sync

(1 row)

 

3.3切換方式

通過觸發器文件方式觸發主備切換和通過pg_ctl promot命令觸發主備切換

一、 文件觸發方式

1)  配置備庫recovery.conf 文件的tigger_file參數,設置激活備庫的觸發文件路徑和名稱。添加tigger_file參數。

trigger_file = ‘/database/pg10/pg_root/.postgresql.trigger.5432’

2)  關閉主庫,使用 -m fast 模式關閉。(數據庫關閉時首先做一次checkpoint,wal進程會將截止此次checkpoint的wal日志流發送給備庫,備庫在應用wal。)

3)  在備庫創建觸發文件激活備庫,當recovery.conf變為recovery.done表示備庫已切換為主庫。

[pgsql@pgstandby ~]$ cat /database/pg10/pg_root/recovery.conf |grep ^[^#]

recovery_target_timeline = 'latest'

standby_mode = on

primary_conninfo='host=192.168.231.131 port=5432 user=repuser application_name=node2'

trigger_file='/database/pg10/pg_root/.postgresql.trigger.5432'

[pgsql@pgstandby ~]$ touch /database/pg10/pg_root/.postgresql.trigger.5432   --創建觸發文件,檢測不到主庫后會自動切換為主庫。

4)  在老主庫下創建recovery.conf文件,並配置相應參數,跟備庫的參數一樣。在根目錄下配置.pgpass免密文件。

 

[pgsql@pgstandby ~]$ vi /database/pg10/pg_root/recovery.conf     --主要依據原來備庫的recovery.conf參數來進行設置。

recovery_target_timeline = 'latest'                      

standby_mode = on

primary_conninfo = 'host=192.168.231.131 port=5432 user=repuser'

       

[pgsql@pgstandby ~]$ cat .pgpass

192.168.231.132:5432:replication:repuser:hufj123

192.168.231.131:5432:replication:repuser:hufj123

 

5)  啟動老的主庫,觀察主備庫是否正常。

 

二、 主備切換之pg_ctl promote方式

pg_ctl promote [ D datadir]

-D 是指數據目錄,如果不指定會使用環境變量 $PGDATA 設置的值。 promote 命令發 出后,運行中的備庫將停止恢復模式並切換成讀寫模式的主庫。 pg_ctl promote 主備切換步驟和文件觸發方式大體相同。

1)關閉主庫,使用-m fast模式

2)備庫執行pg_ctl promote命令激活備庫

3)原主庫切換為備庫,創建recovery.conf文件,配置參數。

4)重新啟動原主庫,查看主備進程是否正常。

四、延遲備庫

配置參數 recovery_min_apply_delay(integer)單位支持天d,時h,分min,秒s,毫秒ms。

 

延遲操作主要是為了防止誤操作,而可以直接在備庫進行數據找回。參數recovery_min_apply_delay設置太大,會導致wal日志占用更多空間,recovery_min_apply_delay參數設置太小,起不到數據恢復的用途。

 

recovery_min_apply_delay注意與參數synchronous_commit的復用。

若synchronous_commit=on;則無影響,只要備庫接受到日志,主庫就可以不用等待延時參數的影響。若synchronous_commit=remote_apply,備庫需要接收到日志,並延時應用wal日志信息,那么主庫就相應的會在延時后才收到備庫的消息,才能繼續下一事務。

 

 

 


免責聲明!

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



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