在CentOS/Ubuntu環(huán)境下搭建PostgreSQL主從復(fù)制

之前做運(yùn)維時(shí)遇到過(guò)這么一件事:凌晨三點(diǎn),數(shù)據(jù)庫(kù)服務(wù)器突然宕機(jī),業(yè)務(wù)直接停擺。值班電話一個(gè)接一個(gè),翻箱倒柜找備用方案,結(jié)果發(fā)現(xiàn)根本沒(méi)有——就一臺(tái)單機(jī) PostgreSQL,掛了就是掛了。
那時(shí)候最痛苦的是:每次做數(shù)據(jù)備份都要手動(dòng)停庫(kù),恢復(fù)時(shí)間以小時(shí)計(jì);監(jiān)控報(bào)警了還得 SSH 登錄查日志;最怕的是主庫(kù)掛了之后,從庫(kù)還傻乎乎等著指令。量化一下痛點(diǎn):一次宕機(jī)損失至少 2 小時(shí)業(yè)務(wù)時(shí)間,數(shù)據(jù)恢復(fù)要 30 分鐘到 1 小時(shí),而且還得人工介入。
后來(lái)?yè)Q了 PostgreSQL 主從復(fù)制,情況變了。
主庫(kù)掛了可以直接從庫(kù)切換,業(yè)務(wù)中斷時(shí)間從小時(shí)級(jí)縮短到分鐘級(jí);自動(dòng)同步保證數(shù)據(jù)不丟失;監(jiān)控一看就知道同不同步、延遲多少。最核心的改變就是:不再把雞蛋放在一個(gè)籃子里,也不再半夜被電話叫醒修數(shù)據(jù)庫(kù)。
如果你也經(jīng)歷過(guò)單點(diǎn)故障的痛,或者正在考慮給數(shù)據(jù)庫(kù)做高可用,下面這套方案可以直接用。
本文將摒棄空泛理論,以CentOS/Ubuntu 環(huán)境下的PostgreSQL 14為例,手把手帶你完成從零搭建、配置調(diào)優(yōu)到故障演練的完整流程。無(wú)論你是DevOps工程師、DBA,還是希望提升系統(tǒng)容災(zāi)能力的開(kāi)發(fā)者,都能通過(guò)本指南,真正掌握PostgreSQL高可用的核心實(shí)踐。
讓數(shù)據(jù)多一份副本,讓服務(wù)少一分風(fēng)險(xiǎn)。
從今天起,告別單點(diǎn)故障,構(gòu)建屬于你的高可用數(shù)據(jù)庫(kù)基石。

1.環(huán)境準(zhǔn)備
1.1 基礎(chǔ)環(huán)境要求
| 節(jié)點(diǎn)類型 | 服務(wù)器地址 | 系統(tǒng)版本 | PostgreSQL 版本 | 核心要求 |
|---|---|---|---|---|
| 主庫(kù)(Master) | 192.168.42.140(示例) | CentOS 7/8/9或Ubuntu 20.04+ | 14 | 開(kāi)啟網(wǎng)絡(luò)端口、關(guān)閉防火墻 / 放行5432端口 |
| 從庫(kù)(Slave/Standby) | 192.168.42.145(示例) | 與主庫(kù)一致 | 與主庫(kù)完全一致 | 與主庫(kù)網(wǎng)絡(luò)互通、磁盤空間不小于主庫(kù) |
1.2 安裝PostgreSQL
還沒(méi)安裝PostgreSQL的小伙伴可以去cpolar官網(wǎng)參考《誰(shuí)說(shuō)沒(méi)公網(wǎng)IP不能遠(yuǎn)程連數(shù)據(jù)庫(kù)?PostgreSQL+cpolar打通任督二脈》這篇文章哦~
2.1 修改PostgreSQL主配置文件
主配置文件路徑:/var/lib/pgsql/14/data/postgresql.conf
vim /var/lib/pgsql/14/data/postgresql.conf
修改以下核心參數(shù)(取消注釋并調(diào)整值):
# 1. 監(jiān)聽(tīng)地址(允許從庫(kù)連接,可指定從庫(kù)IP或0.0.0.0允許所有) listen_addresses = '*' # 2. 開(kāi)啟歸檔模式(主從復(fù)制依賴) archive_mode = on archive_command = 'cp %p /var/lib/pgsql/14/archive/%f' # %p=歸檔文件路徑,%f=歸檔文件名 # 提前創(chuàng)建歸檔目錄 mkdir -p /var/lib/pgsql/14/archive && chown -R postgres:postgres /var/lib/pgsql/14/archive # 3. WAL日志配置(保證復(fù)制可靠性) wal_level = replica # 復(fù)制所需的WAL級(jí)別(replica/archive/logical,replica足夠) wal_buffers = 16MB # 根據(jù)內(nèi)存調(diào)整,默認(rèn)通常足夠 max_wal_senders = 10 # 最大并發(fā)復(fù)制連接數(shù),大于從庫(kù)數(shù)量即可 wal_keep_size = 1GB # 保留WAL日志的大小,防止從庫(kù)同步滯后導(dǎo)致日志被清理 # 4. 同步模式(可選,按需配置) # synchronous_commit = on # 默認(rèn)同步提交,保證主從數(shù)據(jù)一致性;追求性能可設(shè)為off # synchronous_standby_names = 'slave1' # 指定從庫(kù)名稱(需與從庫(kù)recovery.conf對(duì)應(yīng)) # 5. 其他優(yōu)化(可選) max_connections = 1000 # 大于從庫(kù)的max_connections
![]()

2.2 修改客戶端認(rèn)證配置文件
文件路徑:/var/lib/pgsql/14/data/pg_hba.conf
vim /var/lib/pgsql/14/data/pg_hba.conf
添加從庫(kù)的連接授權(quán)(允許從庫(kù) IP 通過(guò)復(fù)制用戶連接):
host replication repl_user 192.168.42.145/32 md5 # 從庫(kù)IP,repl_user為復(fù)制專用用戶 host all all 192.168.42.0/24 md5 # 可選,允許內(nèi)網(wǎng)其他機(jī)器連接

2.3 創(chuàng)建復(fù)制專用用戶
切換到postgres用戶,執(zhí)行 SQL 命令創(chuàng)建用于主從復(fù)制的專用用戶(需授予復(fù)制權(quán)限):
su - postgres psql
執(zhí)行SQL:
-- 創(chuàng)建復(fù)制用戶(密碼自定義,示例:Repl@123456) CREATE ROLE repl_user WITH REPLICATION LOGIN ENCRYPTED PASSWORD '********'; -- 驗(yàn)證用戶(可選) \du repl_user; -- 退出psql \q

2.4 重啟主庫(kù)使配置生效
systemctl restart postgresql-14 systemctl status postgresql-14 sudo -u postgres psql -c "SELECT pg_is_in_recovery();" # 主庫(kù)返回f(非恢復(fù)模式)

2.5 備份主庫(kù)數(shù)據(jù)(供從庫(kù)初始化)
使用pg_basebackup工具備份主庫(kù)數(shù)據(jù),該工具專門用于PostgreSQL復(fù)制環(huán)境的從庫(kù)初始化:
# 切換到postgres用戶 su - postgres # 執(zhí)行備份(備份到臨時(shí)目錄,后續(xù)拷貝到從庫(kù)) pg_basebackup -h 192.168.42.140 -U repl_user -p 5432 -D /tmp/pg_master_backup -F p -X s -P -R # 參數(shù)說(shuō)明: # -h:主庫(kù)地址 # -U:復(fù)制用戶 # -p:主庫(kù)端口 # -D:備份目錄 # -F p:輸出格式為普通文件(與主庫(kù)數(shù)據(jù)目錄結(jié)構(gòu)一致) # -X s:備份過(guò)程中同步復(fù)制WAL日志,保證備份一致性 # -P:顯示備份進(jìn)度 # -R:自動(dòng)生成復(fù)制所需的standby.signal文件和postgresql.auto.conf配置,簡(jiǎn)化從庫(kù)配置

備份完成后,將備份目錄打包拷貝到從庫(kù)的/var/lib/pgsql/14/目錄下(可通過(guò) scp 傳輸):
tar -zcvf pg_master_backup.tar.gz /tmp/pg_master_backup # 主庫(kù)上打包備份
scp pg_master_backup.tar.gz root@192.168.1.101:/var/lib/pgsql/14 # 傳輸?shù)綇膸?kù)

![]()
到從庫(kù)所在地址查看一下是否傳送成功到/var/lib/pgsql/14:
![]()
3.從庫(kù)配置
3.1 停止從庫(kù)PostgreSQL服務(wù)并清理原有數(shù)據(jù)目錄
# 停止從庫(kù)服務(wù) systemctl stop postgresql-14 # 清理原有數(shù)據(jù)目錄(初始化后的空目錄,需替換為主庫(kù)備份) mv /var/lib/pgsql/14/data /var/lib/pgsql/14/data_bak # 備份原有目錄,防止誤刪 mkdir -p /var/lib/pgsql/14/data

3.2 解壓主庫(kù)備份到從庫(kù)數(shù)據(jù)目錄
# 切換到postgres用戶 su - postgres # 解壓備份包 tar -zxvf /var/lib/pgsql/14/pg_master_backup.tar.gz -C /var/lib/pgsql/14/ # 移動(dòng)備份數(shù)據(jù)到data目錄 mv /var/lib/pgsql/14/tmp/pg_master_backup/* /var/lib/pgsql/14/data/ # 修改目錄權(quán)限(必須為postgres用戶和組) chown -R postgres:postgres /var/lib/pgsql/14/data chmod 700 /var/lib/pgsql/14/data


3.3 驗(yàn)證 / 修改從庫(kù)復(fù)制配置
由于主庫(kù)備份時(shí)使用了-R參數(shù),會(huì)自動(dòng)生成standby.signal(標(biāo)識(shí)從庫(kù)身份)和postgresql.auto.conf(包含復(fù)制連接信息),無(wú)需手動(dòng)創(chuàng)建:
# 查看自動(dòng)生成的復(fù)制配置 cat /var/lib/pgsql/14/data/postgresql.auto.conf ls /var/lib/pgsql/14/data/

若沒(méi)有,則手動(dòng)創(chuàng)建standby.signal并修改postgresql.conf:
# 手動(dòng)創(chuàng)建standby.signal(標(biāo)識(shí)為從庫(kù)) touch /var/lib/pgsql/14/data/standby.signal # 編輯postgresql.conf,添加復(fù)制配置,添加以下參數(shù): vim /var/lib/pgsql/14/data/postgresql.conf # 從庫(kù)專屬配置 hot_standby = on # 允許從庫(kù)處于恢復(fù)模式時(shí)提供查詢服務(wù)(只讀) max_connections = 500 # 小于主庫(kù)的max_connections primary_conninfo = 'user=repl_user password=Repl@123456 host=192.168.42.140 port=5432' # 主庫(kù)連接信息
3.4 啟動(dòng)從庫(kù)服務(wù)
# 啟動(dòng)從庫(kù) systemctl start postgresql-14 systemctl enable postgresql-14 # 驗(yàn)證從庫(kù)狀態(tài) systemctl status postgresql-14
4.驗(yàn)證主從復(fù)制是否生效
4.1 主庫(kù)驗(yàn)證復(fù)制狀態(tài)
su - postgres psql # 查看復(fù)制連接狀態(tài)(可看到從庫(kù)的連接信息) SELECT * FROM pg_stat_replication; # 輸出說(shuō)明: # - usename:repl_user(復(fù)制用戶) # - client_addr:192.168.1.101(從庫(kù)IP) # - state:streaming(表示正在流式復(fù)制) # - sync_state:async(異步復(fù)制)或 sync(同步復(fù)制,需主庫(kù)配置synchronous_commit=on)

從提供的pg_stat_replication查詢結(jié)果來(lái)看,PostgreSQL主從復(fù)制已經(jīng)成功建立,并且處于正常運(yùn)行狀態(tài)。這是一個(gè)非常關(guān)鍵的監(jiān)控視圖,用于查看 主庫(kù)上的復(fù)制連接狀態(tài)。
4.2 從庫(kù)驗(yàn)證復(fù)制狀態(tài)
su - postgres psql # 1. 驗(yàn)證是否處于恢復(fù)模式(從庫(kù)返回t,主庫(kù)返回f) SELECT pg_is_in_recovery();

4.3 驗(yàn)證主從數(shù)據(jù)一致性
# 主庫(kù)創(chuàng)建測(cè)試表并插入數(shù)據(jù) # 主庫(kù)執(zhí)行: CREATE DATABASE test_repl; \c test_repl; CREATE TABLE user_info (id int, name varchar(50)); INSERT INTO user_info VALUES (1, 'test_replication'); # 從庫(kù)執(zhí)行(查看是否同步到數(shù)據(jù)) \c test_repl; SELECT * FROM user_info;
主庫(kù):

從庫(kù):

從上圖我們可以看出,主從復(fù)制成功啦!
5.主從復(fù)制常用操作
5.1 切換主從(故障轉(zhuǎn)移,簡(jiǎn)易版)
當(dāng)主庫(kù)故障時(shí),可將從庫(kù)提升為主庫(kù):
# 從庫(kù)執(zhí)行(停止恢復(fù)模式,提升為主庫(kù)) su - postgres psql -c "SELECT pg_promote();" # 驗(yàn)證:提升后從庫(kù)pg_is_in_recovery()返回f psql -c "SELECT pg_is_in_recovery();"
5.2 監(jiān)控復(fù)制延遲
# 從庫(kù)執(zhí)行,查看復(fù)制延遲(單位:秒) SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;
5.3新增從庫(kù)
只需重復(fù) “從庫(kù)配置” 步驟,使用主庫(kù)(或現(xiàn)有從庫(kù),需開(kāi)啟級(jí)聯(lián)復(fù)制)的pg_basebackup備份初始化即可。
5.4 拓展
主從復(fù)制已經(jīng)成功搭建,但我們的目標(biāo)遠(yuǎn)不止于此。
回想一下,在開(kāi)發(fā)、測(cè)試,甚至小型項(xiàng)目交付中,你是否也曾陷入這樣的困境:
- “我在家搭了個(gè)PostgreSQL數(shù)據(jù)庫(kù),同事怎么連不上?”
- “客戶急著看Demo,可服務(wù)跑在內(nèi)網(wǎng),根本沒(méi)法訪問(wèn)!”
- “沒(méi)有公網(wǎng)IP,難道只能租云服務(wù)器,或者干脆放棄遠(yuǎn)程演示?”
別焦慮——沒(méi)有公網(wǎng)IP,并不意味著你的服務(wù)只能困在局域網(wǎng)里。借助一個(gè)輕量級(jí)但強(qiáng)大的內(nèi)網(wǎng)穿透工具,你可以輕松將本地運(yùn)行的PostgreSQL服務(wù)“暴露”到公網(wǎng),自動(dòng)生成一個(gè)安全、可分享的HTTPS隧道地址。無(wú)論你身處家庭寬帶、公司防火墻后,還是校園網(wǎng)深處,外部用戶都能像訪問(wèn)普通網(wǎng)站一樣,通過(guò)標(biāo)準(zhǔn)端口安全連接你的數(shù)據(jù)庫(kù)。本文將手把手帶你完成這一過(guò)程:從零配置,到安全地將PostgreSQL服務(wù)映射至公網(wǎng),打通內(nèi)網(wǎng)與外部世界的連接通道。從此,“我的數(shù)據(jù)庫(kù)在哪,服務(wù)就在哪” 不再是一句空話。準(zhǔn)備好了嗎?讓我們開(kāi)啟這場(chǎng)高效、安全、低成本的“內(nèi)網(wǎng)突圍”之旅!
6.實(shí)現(xiàn)隨時(shí)隨地開(kāi)發(fā)
6.1 它是什么?
它是一款安全高效的內(nèi)網(wǎng)穿透工具,無(wú)需公網(wǎng)IP或復(fù)雜配置,只需一條命令,即可將本地服務(wù)器、Web服務(wù)或任意端口映射到公網(wǎng),讓你隨時(shí)隨地遠(yuǎn)程訪問(wèn)內(nèi)網(wǎng)應(yīng)用,特別適合開(kāi)發(fā)調(diào)試、遠(yuǎn)程運(yùn)維和應(yīng)急部署等場(chǎng)景。
6.2 部署
它可以將你本地電腦中的服務(wù)(如 SSH、Web、數(shù)據(jù)庫(kù))映射到公網(wǎng)。即使你在家里或外出時(shí),也可以通過(guò)公網(wǎng)地址連接回本地運(yùn)行的開(kāi)發(fā)環(huán)境。
??以下是安裝步驟:
使用一鍵腳本安裝命令:
sudo curl https://get.cpolar.sh | sh

安裝完成后,執(zhí)行下方命令查看
sudo systemctl status cpolar

安裝和成功啟動(dòng)服務(wù)后,在瀏覽器上輸入虛擬機(jī)主機(jī)IP加9200端口即:http://localhost:9200訪問(wèn)管理界面,使用官網(wǎng)注冊(cè)的賬號(hào)登錄,登錄后即可看到web 配置界面,接下來(lái)在web 界面配置即可:
打開(kāi)瀏覽器訪問(wèn)本地9200端口,使用賬戶密碼登錄即可,登錄后即可對(duì)隧道進(jìn)行管理。

7.配置公網(wǎng)地址
通過(guò)配置,你可以在本地 WSL 或 Linux 系統(tǒng)上運(yùn)行 SSH 服務(wù),并通過(guò) 它將其映射到公網(wǎng),從而實(shí)現(xiàn)從任意設(shè)備遠(yuǎn)程連接開(kāi)發(fā)環(huán)境的目的。
- 隧道名稱:可自定義,本例使用了:postgres,注意不要與已有的隧道名稱重復(fù)
- 協(xié)議:tcp
- 本地地址:192.168.42.140:5432
- 端口類型:隨機(jī)臨時(shí)TCP端口
- 地區(qū):China Vip

創(chuàng)建成功后,打開(kāi)左側(cè)在線隧道列表,可以看到剛剛通過(guò)創(chuàng)建隧道生成了公網(wǎng)地址,接下來(lái)就可以在其他電腦或者移動(dòng)端設(shè)備(異地)上,使用任意一個(gè)地址在終端中訪問(wèn)即可。
tcp 表示使用的協(xié)議類型
2.tcp.vip.cpolar.cn是 Cpolar 提供的域名
11084是隨機(jī)分配的公網(wǎng)端口號(hào)

通過(guò)它提供的公網(wǎng)地址和端口,使用 SSH 協(xié)議從任意一臺(tái)主機(jī)連接到postgres賬號(hào)啦!
psql -h 2.tcp.vip.cpolar.cn -p 11084 -U postgres -d mydb

8.保留固定TCP公網(wǎng)地址
使用為其配置TCP地址,該地址為固定地址,不會(huì)隨機(jī)變化。

選擇區(qū)域和描述:有一個(gè)下拉菜單,當(dāng)前選擇的是“China VIP”。
右側(cè)輸入框,用于填寫(xiě)描述信息。
保留按鈕:在右側(cè)有一個(gè)橙色的“保留”按鈕,點(diǎn)擊該按鈕可以保留所選的TCP地址。
列表中顯示了一條已保留的TCP地址記錄。
地區(qū):顯示為“China VIP”。
地址:顯示為“8.tcp.vip.cpolar.cn:13299”。

登錄web UI管理界面,點(diǎn)擊左側(cè)儀表盤的隧道管理——隧道列表,找到所要配置的隧道postgres,點(diǎn)擊右側(cè)的編輯。

修改隧道信息,將保留成功的TCP端口配置到隧道中。
- 端口類型:選擇固定TCP端口
- 預(yù)留的TCP地址:填寫(xiě)保留成功的TCP地址
點(diǎn)擊更新。

創(chuàng)建完成后,打開(kāi)在線隧道列表,此時(shí)可以看到隨機(jī)的公網(wǎng)地址已經(jīng)發(fā)生變化,地址名稱也變成了保留和固定的TCP地址。
最后測(cè)試一下固定的地址是否好用,測(cè)試命令:
psql -h 8.tcp.vip.cpolar.cn -p 13299 -U postgres -d mydb

這樣,我們成功打破了“沒(méi)有公網(wǎng) IP 就無(wú)法遠(yuǎn)程訪問(wèn)數(shù)據(jù)庫(kù)”的固有認(rèn)知。
總結(jié)
對(duì)比下來(lái),單庫(kù)和主從復(fù)制的差別很明顯:
*不用主從復(fù)制時(shí):*
- 數(shù)據(jù)庫(kù)宕機(jī) = 業(yè)務(wù)停擺,恢復(fù)靠手動(dòng)
- 備份要停機(jī),數(shù)據(jù)有丟失風(fēng)險(xiǎn)
- 維護(hù)升級(jí)必須 downtime
- 全靠人工救火
*用了主從復(fù)制后:*
- 主庫(kù)掛了可以快速切換到從庫(kù)
- 數(shù)據(jù)實(shí)時(shí)同步,最多丟失幾秒
- 從庫(kù)可以分擔(dān)讀取壓力
- 運(yùn)維從救火變成預(yù)防
不過(guò)也得承認(rèn),主從復(fù)制不是萬(wàn)能藥:配置錯(cuò)了照樣出問(wèn)題,網(wǎng)絡(luò)不穩(wěn)定會(huì)有延遲,高并發(fā)場(chǎng)景還要考慮讀寫(xiě)分離。而且,異步復(fù)制模式下主庫(kù)掛了還是可能有數(shù)據(jù)丟失,真正要求不丟數(shù)據(jù)得上同步復(fù)制或者 PgPool 這種更復(fù)雜的方案。
如果你也有類似的痛點(diǎn),比如擔(dān)心單點(diǎn)故障、想降低運(yùn)維壓力,可以試試這個(gè)方案。先在測(cè)試環(huán)境跑通再上生產(chǎn),別直接懟線上。
到此這篇關(guān)于在CentOS/Ubuntu環(huán)境下搭建PostgreSQL主從復(fù)制的文章就介紹到這了,更多相關(guān)PostgreSQL主從復(fù)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PostgreSQL無(wú)法查看表中數(shù)據(jù)問(wèn)題的原因和解決方法
在 PostgreSQL 中,恢復(fù)數(shù)據(jù)庫(kù)后,使用 DBeaver 等工具可以看到數(shù)據(jù)庫(kù)和表名,但無(wú)法查詢到表中數(shù)據(jù),可能有很多原因,本文給大家分析了PostgreSQL無(wú)法查看表中數(shù)據(jù)問(wèn)題的原因和解決方法,需要的朋友可以參考下2025-04-04
將PostgreSQL的數(shù)據(jù)實(shí)時(shí)同步到Doris的技巧分享
眾所周知,在兩個(gè)毫不相干的數(shù)據(jù)管理系統(tǒng)之間進(jìn)行數(shù)據(jù)同步,特別是實(shí)時(shí)同步,其復(fù)雜程度足以讓高級(jí)DBA腦瓜疼,本文給大家介紹了將PostgreSQL的數(shù)據(jù)實(shí)時(shí)同步到Doris的技巧分享,需要的朋友可以參考下2024-03-03
淺談PostgreSQL消耗的內(nèi)存計(jì)算方法
這篇文章主要介紹了淺談PostgreSQL消耗的內(nèi)存計(jì)算方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
使用PostgreSQL為表或視圖創(chuàng)建備注的操作
這篇文章主要介紹了使用PostgreSQL為表或視圖創(chuàng)建備注的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
postgresql?IvorySQL新增命令及相關(guān)配置參數(shù)詳解
這篇文章主要為大家介紹了postgresql?IvorySQL新增命令及相關(guān)配置參數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12

