Docker下配置PostgreSQL主從復(fù)制的詳細(xì)步驟指南
在實(shí)際生產(chǎn)環(huán)境中,PostgreSQL(簡稱 Pgsql)作為一款強(qiáng)大的開源關(guān)系型數(shù)據(jù)庫,單節(jié)點(diǎn)部署存在明顯的單點(diǎn)故障風(fēng)險(xiǎn)——一旦主庫宕機(jī),將直接導(dǎo)致業(yè)務(wù)中斷、數(shù)據(jù)丟失,嚴(yán)重影響系統(tǒng)可用性。而主從復(fù)制技術(shù),正是解決這一痛點(diǎn)的核心方案:通過搭建主庫(Master)與從庫(Slave)架構(gòu),主庫負(fù)責(zé)處理所有寫操作(增刪改),從庫實(shí)時(shí)同步主庫數(shù)據(jù)并提供讀操作支持,既能實(shí)現(xiàn)數(shù)據(jù)備份,又能分擔(dān)主庫讀壓力,同時(shí)在主庫故障時(shí)可快速切換到從庫,保障業(yè)務(wù)連續(xù)性。
Docker 作為輕量級(jí)容器化工具,能夠快速部署、隔離 Pgsql 實(shí)例,大幅降低主從復(fù)制的環(huán)境搭建復(fù)雜度,無需擔(dān)心不同系統(tǒng)的環(huán)境差異,實(shí)現(xiàn)“一次配置,多環(huán)境復(fù)用”。本文將以通俗易懂的語言,結(jié)合詳細(xì)的示例代碼,從環(huán)境準(zhǔn)備、主庫配置、從庫配置、同步驗(yàn)證、故障排查到進(jìn)階拓展,完整講解 Docker 下 Pgsql 主從復(fù)制的配置全過程,適合新手入門和運(yùn)維人員實(shí)操參考。
一、核心概念與前置說明
在開始配置前,先明確幾個(gè)核心概念,避免后續(xù)操作混淆,同時(shí)梳理好前置準(zhǔn)備工作,確保配置過程順暢。
1.1 主從復(fù)制核心原理
Pgsql 主從復(fù)制基于 WAL(Write-Ahead Log,預(yù)寫日志) 實(shí)現(xiàn),核心流程如下:
- 主庫執(zhí)行所有寫操作時(shí),會(huì)先將操作記錄寫入 WAL 日志文件;
- 從庫通過專用復(fù)制用戶連接主庫,實(shí)時(shí)獲取主庫的 WAL 日志;
- 從庫將獲取到的 WAL 日志解析并重放,從而同步主庫的數(shù)據(jù),保持主從數(shù)據(jù)一致性。
根據(jù) WAL 日志的同步方式,Pgsql 主從復(fù)制主要分為兩種:
- 異步復(fù)制(默認(rèn)):主庫寫入 WAL 日志后,無需等待從庫確認(rèn)接收,即可返回寫操作成功。優(yōu)點(diǎn)是性能好,缺點(diǎn)是主庫宕機(jī)時(shí),可能存在少量未同步的數(shù)據(jù)丟失,適合對(duì)數(shù)據(jù)一致性要求不極致的場(chǎng)景。
- 同步復(fù)制:主庫寫入 WAL 日志后,必須等待至少一個(gè)從庫確認(rèn)接收并寫入本地磁盤,才能返回寫操作成功。優(yōu)點(diǎn)是數(shù)據(jù)一致性高,無數(shù)據(jù)丟失風(fēng)險(xiǎn),缺點(diǎn)是主庫寫性能會(huì)受網(wǎng)絡(luò)延遲影響,適合金融、電商等對(duì)數(shù)據(jù)一致性要求極高的場(chǎng)景。
本文將先實(shí)現(xiàn)最常用的異步復(fù)制,后續(xù)拓展部分會(huì)講解如何切換為同步復(fù)制。
1.2 前置準(zhǔn)備
確保你的環(huán)境滿足以下條件,避免配置過程中出現(xiàn)異常:
- 已安裝 Docker 和 Docker Compose(推薦使用 Docker Compose 管理容器,簡化配置和啟動(dòng)流程);
- 服務(wù)器空閑端口:主庫默認(rèn)使用 5432 端口,從庫建議使用 5433 端口(可自定義,需確保端口未被占用);
- 網(wǎng)絡(luò)通暢:主從容器需在同一網(wǎng)絡(luò)下,確保從庫能正常訪問主庫的 5432 端口;
- Pgsql 鏡像:推薦使用官方鏡像(postgres:14,穩(wěn)定版,兼容性好),避免使用第三方鏡像導(dǎo)致配置異常。
驗(yàn)證 Docker 環(huán)境(終端執(zhí)行以下命令):
# 驗(yàn)證 Docker 是否啟動(dòng) docker --version # 驗(yàn)證 Docker Compose 是否安裝 docker compose --version
若均能正常顯示版本信息,說明 Docker 環(huán)境就緒。
二、Docker 環(huán)境搭建 Pgsql 主從架構(gòu)(詳細(xì)步驟)
本次配置采用“單主單從”架構(gòu)(最基礎(chǔ)、最常用的架構(gòu)),使用 Docker Compose 統(tǒng)一管理主從容器,步驟分為:創(chuàng)建自定義網(wǎng)絡(luò)、編寫 Docker Compose 配置、啟動(dòng)容器、配置主庫、配置從庫、驗(yàn)證同步,每一步都提供詳細(xì)示例代碼,可直接復(fù)制實(shí)操。
2.1 第一步:創(chuàng)建自定義 Docker 網(wǎng)絡(luò)
為了讓主從容器能夠通過容器名直接通信(避免使用 IP 地址,減少配置復(fù)雜度),我們先創(chuàng)建一個(gè)自定義的 Docker 網(wǎng)絡(luò),主從容器都加入該網(wǎng)絡(luò)。
# 創(chuàng)建自定義網(wǎng)絡(luò)(網(wǎng)絡(luò)名:pg_network,可自定義) docker network create pg_network # 查看網(wǎng)絡(luò)是否創(chuàng)建成功 docker network ls
執(zhí)行后,若能在網(wǎng)絡(luò)列表中看到 pg\_network,說明網(wǎng)絡(luò)創(chuàng)建成功。后續(xù)主從容器將通過該網(wǎng)絡(luò)通信,主庫容器名可直接作為“主機(jī)名”被從庫訪問。
2.2 第二步:編寫 Docker Compose 配置文件
創(chuàng)建一個(gè)工作目錄(如pg\-master\-slave),在目錄下創(chuàng)建 docker\-compose\.yml 文件,該文件將定義主庫(pg-master)和從庫(pg-slave)的容器配置,包括鏡像、端口映射、數(shù)據(jù)掛載、環(huán)境變量等。
示例代碼(可直接復(fù)制,注釋已詳細(xì)說明每個(gè)配置的作用):
version: '3.8' # Docker Compose 版本,兼容大多數(shù) Docker 版本
services:
# 主庫配置(pg-master)
pg-master:
image: postgres:14 # 使用 Pgsql 14 官方鏡像
container_name: pg-master # 容器名,用于從庫連接
restart: always # 容器異常退出時(shí)自動(dòng)重啟
network_mode: pg_network # 加入自定義網(wǎng)絡(luò)
ports:
- "5432:5432" # 端口映射:宿主機(jī)5432端口 → 容器5432端口(主庫默認(rèn)端口)
environment:
- POSTGRES_USER=postgres # 數(shù)據(jù)庫超級(jí)管理員用戶名
- POSTGRES_PASSWORD=123456 # 數(shù)據(jù)庫超級(jí)管理員密碼(生產(chǎn)環(huán)境請(qǐng)修改為復(fù)雜密碼)
- POSTGRES_DB=testdb # 初始化默認(rèn)數(shù)據(jù)庫(可自定義)
volumes:
# 數(shù)據(jù)掛載:將宿主機(jī)目錄 ./master/data 掛載到容器 /var/lib/postgresql/data
# 作用:持久化主庫數(shù)據(jù),容器刪除后數(shù)據(jù)不丟失
- ./master/data:/var/lib/postgresql/data
# 配置文件掛載:后續(xù)將主庫配置文件放在 ./master/conf 目錄,掛載到容器對(duì)應(yīng)位置
- ./master/conf:/var/lib/postgresql/data/conf
# 啟動(dòng)后執(zhí)行的命令(確保配置文件目錄權(quán)限正確)
command: ["sh", "-c", "chmod 700 /var/lib/postgresql/data && exec postgres"]
# 從庫配置(pg-slave)
pg-slave:
image: postgres:14 # 與主庫使用相同版本的鏡像,避免版本兼容問題
container_name: pg-slave # 容器名
restart: always
network_mode: pg_network
ports:
- "5433:5432" # 端口映射:宿主機(jī)5433端口 → 容器5432端口(避免與主庫端口沖突)
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=123456 # 與主庫超級(jí)管理員密碼一致,方便管理
- POSTGRES_DB=testdb
volumes:
- ./slave/data:/var/lib/postgresql/data
- ./slave/conf:/var/lib/postgresql/data/conf
command: ["sh", "-c", "chmod 700 /var/lib/postgresql/data && exec postgres"]
# 依賴主庫:確保主庫啟動(dòng)后,再啟動(dòng)從庫(避免從庫先啟動(dòng)無法連接主庫)
depends_on:
- pg-master配置說明:
- 數(shù)據(jù)掛載:通過
volumes掛載宿主機(jī)目錄,確保容器刪除后,Pgsql 數(shù)據(jù)不會(huì)丟失,同時(shí)方便后續(xù)修改配置文件; - 網(wǎng)絡(luò)配置:
network\_mode: pg\_network表示主從容器都加入自定義網(wǎng)絡(luò),可通過容器名(pg-master、pg-slave)直接通信; - 依賴配置:
depends\_on: \[pg\-master\]確保主庫先啟動(dòng),避免從庫啟動(dòng)時(shí)主庫未就緒,導(dǎo)致連接失??; - 權(quán)限設(shè)置:
chmod 700 /var/lib/postgresql/data確保 Pgsql 數(shù)據(jù)目錄權(quán)限正確(Pgsql 要求數(shù)據(jù)目錄權(quán)限為 700,否則無法啟動(dòng))。
2.3 第三步:啟動(dòng)主從容器
在 docker\-compose\.yml 文件所在目錄,執(zhí)行以下命令啟動(dòng)主從容器:
# 啟動(dòng)容器(后臺(tái)運(yùn)行) docker compose up -d # 查看容器啟動(dòng)狀態(tài) docker compose ps
若輸出中 pg\-master 和pg\-slave 的狀態(tài)均為 Up,說明容器啟動(dòng)成功。若啟動(dòng)失敗,可通過 docker logs pg\-master 或 docker logs pg\-slave 查看日志,排查錯(cuò)誤(常見錯(cuò)誤為端口占用、數(shù)據(jù)目錄權(quán)限不足)。
2.4 第四步:配置主庫(關(guān)鍵步驟)
主庫的核心配置的是:開啟 WAL 日志、創(chuàng)建復(fù)制專用用戶、配置訪問權(quán)限,允許從庫連接并獲取 WAL 日志。
2.4.1 進(jìn)入主庫容器
# 進(jìn)入主庫容器(容器名:pg-master) docker exec -it pg-master bash
進(jìn)入容器后,默認(rèn)處于 / 目錄,接下來需要修改 Pgsql 的核心配置文件 postgresql\.conf 和pg\_hba\.conf(這兩個(gè)文件位于容器內(nèi) /var/lib/postgresql/data 目錄下)。
2.4.2 修改主庫 postgresql.conf 配置
該文件是 Pgsql 的核心配置文件,需開啟 WAL 日志相關(guān)配置,支持主從復(fù)制。
# 進(jìn)入 Pgsql 數(shù)據(jù)目錄(配置文件所在目錄) cd /var/lib/postgresql/data # 使用 vi 編輯 postgresql.conf(若容器內(nèi)無 vi,可先執(zhí)行 apt update && apt install -y vim) vi postgresql.conf
找到以下配置項(xiàng),修改為對(duì)應(yīng)值(若配置項(xiàng)被注釋,先取消注釋;若不存在,直接添加到文件末尾):
# 1. 監(jiān)聽所有IP地址(允許從庫遠(yuǎn)程連接) listen_addresses = '*' # 2. 開啟 WAL 日志歸檔(主從復(fù)制必需) archive_mode = on # 3. WAL 日志歸檔命令(將 WAL 日志復(fù)制到歸檔目錄,這里簡化配置,實(shí)際可自定義路徑) archive_command = 'cp %p /var/lib/postgresql/data/pg_archive/%f' # 4. WAL 日志級(jí)別(設(shè)置為 replica,支持主從復(fù)制) wal_level = replica # 5. 最大 WAL 發(fā)送進(jìn)程數(shù)(控制從庫最大連接數(shù),建議設(shè)置為從庫數(shù)量+1,這里設(shè)為5) max_wal_senders = 5 # 6. WAL 日志保留數(shù)量(單位:個(gè),每個(gè) WAL 日志默認(rèn)16MB,保留64個(gè)即1024MB,避免從庫同步時(shí)日志被刪除) wal_keep_segments = 64 # 7. WAL 發(fā)送超時(shí)時(shí)間(從庫連接超時(shí)時(shí)間,設(shè)為60秒) wal_sender_timeout = 60s # 8. 主庫最大連接數(shù)(建議從庫最大連接數(shù)大于主庫,避免從庫連接數(shù)不足) max_connections = 100
配置說明:
archive\_mode = on:開啟 WAL 日志歸檔,確保主庫的 WAL 日志不會(huì)被自動(dòng)清理,以便從庫同步;wal\_level = replica:設(shè)置 WAL 日志級(jí)別為 replica,支持主從復(fù)制所需的日志信息;max\_wal\_senders:控制從庫最大連接數(shù),若有多個(gè)從庫,需適當(dāng)增大該值。
修改完成后,保存并退出 vi(按 Esc,輸入 :wq 回車)。
2.4.3 創(chuàng)建 WAL 歸檔目錄
由于上面配置了 archive\_command,需要?jiǎng)?chuàng)建對(duì)應(yīng)的歸檔目錄,并設(shè)置權(quán)限:
# 在主庫數(shù)據(jù)目錄下創(chuàng)建歸檔目錄 mkdir -p /var/lib/postgresql/data/pg_archive # 設(shè)置目錄權(quán)限(與數(shù)據(jù)目錄一致,為700) chmod 700 /var/lib/postgresql/data/pg_archive
2.4.4 修改主庫 pg_hba.conf 配置
該文件是 Pgsql 的訪問控制配置文件,用于控制哪些 IP、哪些用戶可以訪問數(shù)據(jù)庫,需添加從庫的訪問權(quán)限,允許復(fù)制用戶連接。
# 繼續(xù)在數(shù)據(jù)目錄下,編輯 pg_hba.conf vi pg_hba.conf
在文件末尾添加以下內(nèi)容(允許從庫通過復(fù)制用戶連接主庫):
# 允許從庫(同一自定義網(wǎng)絡(luò)下的所有IP)使用復(fù)制用戶連接主庫 # 格式:host 數(shù)據(jù)庫類型 用戶名 允許訪問的IP 認(rèn)證方式 host replication replica 172.18.0.0/16 trust # 可選:允許宿主機(jī)訪問主庫(方便本地測(cè)試) host all all 0.0.0.0/0 md5
配置說明:
replication:表示數(shù)據(jù)庫類型為復(fù)制(主從復(fù)制專用);replica:后續(xù)將創(chuàng)建的復(fù)制專用用戶名(可自定義);172\.18\.0\.0/16:自定義 Docker 網(wǎng)絡(luò)的網(wǎng)段(可通過docker network inspect pg\_network查看網(wǎng)段,替換為實(shí)際網(wǎng)段);trust:認(rèn)證方式為信任(同一網(wǎng)絡(luò)下,無需密碼即可連接,適合測(cè)試環(huán)境;生產(chǎn)環(huán)境建議改為md5,需輸入密碼)。
修改完成后,保存并退出 vi。
2.4.5 創(chuàng)建復(fù)制專用用戶
進(jìn)入 Pgsql 客戶端,創(chuàng)建一個(gè)具備 replication(復(fù)制)權(quán)限的專用用戶,用于從庫連接主庫同步數(shù)據(jù)(避免使用超級(jí)管理員用戶,提升安全性)。
# 進(jìn)入 Pgsql 客戶端(使用超級(jí)管理員用戶 postgres) psql -U postgres # 創(chuàng)建復(fù)制專用用戶(用戶名:replica,密碼:replica123,可自定義) CREATE ROLE replica LOGIN REPLICATION ENCRYPTED PASSWORD 'replica123'; # 驗(yàn)證用戶是否創(chuàng)建成功(查看所有用戶) \du # 退出 Pgsql 客戶端 \q
執(zhí)行 \\du 后,若能看到 replica 用戶,且 Attributes 包含 Replication,說明用戶創(chuàng)建成功。
2.4.6 重啟主庫容器,使配置生效
主庫配置修改完成后,需重啟容器,讓配置生效:
# 退出主庫容器 exit # 重啟主庫容器 docker restart pg-master # 查看主庫容器日志,確認(rèn)重啟成功 docker logs pg-master
若日志中出現(xiàn) database system is ready to accept connections,說明主庫重啟成功,主庫配置完成。
2.5 第五步:配置從庫(關(guān)鍵步驟)
從庫的核心配置是:初始化主庫數(shù)據(jù)(通過基礎(chǔ)備份同步主庫現(xiàn)有數(shù)據(jù))、配置從庫連接主庫的信息,開啟熱備模式,實(shí)現(xiàn)實(shí)時(shí)同步。
2.5.1 進(jìn)入從庫容器
# 進(jìn)入從庫容器(容器名:pg-slave) docker exec -it pg-slave bash
2.5.2 清空從庫默認(rèn)數(shù)據(jù)(關(guān)鍵)
從庫需要同步主庫的完整數(shù)據(jù),因此需先清空從庫默認(rèn)生成的數(shù)據(jù)目錄(避免數(shù)據(jù)沖突):
# 進(jìn)入從庫數(shù)據(jù)目錄 cd /var/lib/postgresql/data # 清空數(shù)據(jù)目錄(注意:執(zhí)行前確認(rèn)是從庫容器,避免誤刪主庫數(shù)據(jù)) rm -rf *
2.5.3 從主庫同步基礎(chǔ)數(shù)據(jù)(使用 pg_basebackup)
pg\_basebackup 是 Pgsql 官方提供的基礎(chǔ)備份工具,可快速將主庫的完整數(shù)據(jù)備份到從庫,為后續(xù)同步奠定基礎(chǔ)。
# 執(zhí)行基礎(chǔ)備份(同步主庫數(shù)據(jù)到從庫) pg_basebackup -h pg-master -U replica -D /var/lib/postgresql/data -X stream -P
命令參數(shù)說明:
\-h pg\-master:主庫的主機(jī)名(即主庫容器名,因主從在同一網(wǎng)絡(luò),可直接使用容器名);\-U replica:復(fù)制專用用戶名(主庫創(chuàng)建的 replica 用戶);\-D /var/lib/postgresql/data:備份數(shù)據(jù)的存儲(chǔ)目錄(從庫數(shù)據(jù)目錄);\-X stream:流式備份,同步主庫的 WAL 日志,確保備份數(shù)據(jù)的一致性;\-P:顯示備份進(jìn)度(方便查看備份是否正常進(jìn)行)。
執(zhí)行命令后,會(huì)提示輸入復(fù)制用戶(replica)的密碼(即 replica123),輸入后開始備份,等待備份完成(備份速度取決于主庫數(shù)據(jù)量,小型測(cè)試庫幾秒即可完成)。
備份完成后,從庫數(shù)據(jù)目錄將包含與主庫完全一致的數(shù)據(jù)。
2.5.4 配置從庫 recovery.conf 文件(PostgreSQL 12+ 版本)
PostgreSQL 12 及以上版本,recovery\.conf 文件已被整合到 postgresql\.conf 中,無需單獨(dú)創(chuàng)建,只需在從庫的 postgresql\.conf 中添加從庫相關(guān)配置,或創(chuàng)建 standby\.signal 文件(標(biāo)記從庫身份)。
我們采用更簡潔的方式,創(chuàng)建 standby\.signal 文件,并修改 postgresql\.conf 配置:
# 1. 在從庫數(shù)據(jù)目錄下,創(chuàng)建 standby.signal 文件(標(biāo)記該節(jié)點(diǎn)為從庫) touch /var/lib/postgresql/data/standby.signal # 2. 編輯從庫 postgresql.conf 文件 vi /var/lib/postgresql/data/postgresql.conf
找到以下配置項(xiàng),修改為對(duì)應(yīng)值(重點(diǎn)配置從庫相關(guān)參數(shù)):
# 1. 監(jiān)聽所有IP地址 listen_addresses = '*' # 2. 開啟熱備模式(從庫可提供只讀服務(wù),同時(shí)同步主庫數(shù)據(jù)) hot_standby = on # 3. 從庫最大連接數(shù)(建議大于主庫,分擔(dān)讀壓力) max_connections = 200 # 4. 流復(fù)制最大延遲時(shí)間(超過該時(shí)間,從庫將停止接收 WAL 日志,默認(rèn)30秒) max_standby_streaming_delay = 30s # 5. 從庫向主庫報(bào)告狀態(tài)的間隔時(shí)間(默認(rèn)10秒) wal_receiver_status_interval = 10s # 6. 從庫反饋(若從庫有長時(shí)間運(yùn)行的查詢,通知主庫不要清理相關(guān) WAL 日志) hot_standby_feedback = on # 7. 從庫連接主庫的配置(核心) primary_conninfo = 'host=pg-master port=5432 user=replica password=replica123' # 8. 同步到最新的時(shí)間線(確保從庫同步主庫的所有數(shù)據(jù)) recovery_target_timeline = 'latest'
關(guān)鍵配置說明:
hot\_standby = on:開啟熱備模式,從庫在同步主庫數(shù)據(jù)的同時(shí),可提供只讀查詢服務(wù),分擔(dān)主庫讀壓力;primary\_conninfo:從庫連接主庫的核心配置,包含主庫主機(jī)名、端口、復(fù)制用戶、密碼,與主庫配置一致;recovery\_target\_timeline = \&\#39;latest\&\#39;:確保從庫同步主庫的最新數(shù)據(jù),即使主庫發(fā)生故障切換,也能同步到最新時(shí)間線。
修改完成后,保存并退出 vi。
2.5.5 重啟從庫容器,使配置生效
# 退出從庫容器 exit # 重啟從庫容器 docker restart pg-slave # 查看從庫容器日志,確認(rèn)重啟成功 docker logs pg-slave
若日志中出現(xiàn)entering standby mode(進(jìn)入 standby 模式)和 started streaming WAL from primary(開始從主庫流式同步 WAL 日志),說明從庫配置成功,已開始同步主庫數(shù)據(jù)。
2.6 第六步:驗(yàn)證主從復(fù)制是否成功(核心驗(yàn)證)
配置完成后,需通過實(shí)際操作驗(yàn)證主從復(fù)制是否正常,確保主庫的寫操作能實(shí)時(shí)同步到從庫。
2.6.1 驗(yàn)證主庫復(fù)制狀態(tài)
進(jìn)入主庫容器,查看從庫的連接狀態(tài),確認(rèn)從庫已成功連接主庫:
# 進(jìn)入主庫容器 docker exec -it pg-master bash # 進(jìn)入 Pgsql 客戶端 psql -U postgres # 查看主庫復(fù)制狀態(tài)(核心查詢語句) SELECT * FROM pg_stat_replication;
若查詢結(jié)果中包含一條記錄,且 state 字段為 streaming(表示正在流式復(fù)制)、usename 為 replica、client\_addr 為從庫的 IP 地址,說明從庫已成功連接主庫,正在同步數(shù)據(jù)。
2.6.2 驗(yàn)證數(shù)據(jù)同步(寫主庫,讀從庫)
通過“主庫寫入數(shù)據(jù),從庫讀取數(shù)據(jù)”的方式,驗(yàn)證同步是否正常:
- 主庫寫入數(shù)據(jù):
# 主庫 Pgsql 客戶端中,執(zhí)行以下 SQL(創(chuàng)建表、插入數(shù)據(jù)) CREATE TABLE test_repl ( id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); # 插入一條測(cè)試數(shù)據(jù) INSERT INTO test_repl (name) VALUES ('Docker Pgsql 主從復(fù)制測(cè)試'); # 查看主庫數(shù)據(jù) SELECT * FROM test_repl;
- 從庫讀取數(shù)據(jù):
# 打開新的終端,進(jìn)入從庫容器 docker exec -it pg-slave bash # 進(jìn)入從庫 Pgsql 客戶端 psql -U postgres # 查看從庫數(shù)據(jù)(確認(rèn)是否同步主庫數(shù)據(jù)) SELECT * FROM test_repl;`
若從庫能查詢到主庫插入的測(cè)試數(shù)據(jù),說明主從復(fù)制正常生效。
2.6.3 驗(yàn)證從庫只讀模式
從庫開啟熱備模式(hot\_standby = on)后,僅支持只讀操作,無法執(zhí)行寫操作(如插入、修改、刪除),驗(yàn)證如下:
# 從庫 Pgsql 客戶端中,嘗試插入數(shù)據(jù)
INSERT INTO test_repl (name) VALUES ('從庫寫入測(cè)試');
# 預(yù)期結(jié)果:報(bào)錯(cuò),提示從庫處于只讀模式
# 錯(cuò)誤信息示例:ERROR: cannot execute INSERT in a read-only transaction
報(bào)錯(cuò)說明從庫只讀模式生效,符合主從復(fù)制的設(shè)計(jì)(寫操作僅在主庫執(zhí)行,從庫負(fù)責(zé)讀和備份)。
三、進(jìn)階拓展:優(yōu)化與故障處理
完成基礎(chǔ)主從復(fù)制配置后,結(jié)合實(shí)際生產(chǎn)場(chǎng)景,補(bǔ)充一些實(shí)用的拓展技巧,包括同步模式切換、故障轉(zhuǎn)移、性能優(yōu)化和常見問題排查,讓主從架構(gòu)更穩(wěn)定、更實(shí)用。
3.1 切換為同步復(fù)制(提升數(shù)據(jù)一致性)
默認(rèn)配置為異步復(fù)制,若需要更高的數(shù)據(jù)一致性(如金融場(chǎng)景),可修改主庫配置,切換為同步復(fù)制:
# 1. 進(jìn)入主庫容器,編輯 postgresql.conf docker exec -it pg-master bash vi /var/lib/postgresql/data/postgresql.conf # 2. 添加/修改以下配置 # 同步復(fù)制模式(on 表示同步,off 表示異步) synchronous_commit = on # 指定同步的從庫名稱(從庫容器名,可多個(gè),用逗號(hào)分隔) synchronous_standby_names = 'pg-slave' # 3. 保存退出,重啟主庫容器 exit docker restart pg-master
切換后,主庫執(zhí)行寫操作時(shí),會(huì)等待從庫確認(rèn)接收 WAL 日志并寫入本地磁盤,才會(huì)返回成功,確保主從數(shù)據(jù)完全一致。但需注意:若從庫宕機(jī),主庫的寫操作會(huì)被阻塞,因此同步復(fù)制建議搭配“一主多從”架構(gòu)。
3.2 主庫故障轉(zhuǎn)移(從庫提升為主庫)
當(dāng)主庫宕機(jī)(如容器崩潰、服務(wù)器故障)時(shí),需將從庫提升為主庫,保障業(yè)務(wù)正常運(yùn)行,步驟如下:
# 1. 進(jìn)入從庫容器,停止從庫的 standby 模式(提升為主庫) docker exec -it pg-slave bash psql -U postgres # 執(zhí)行提升命令(停止恢復(fù)模式,成為主庫) SELECT pg_promote(); # 驗(yàn)證:查詢從庫是否已成為主庫(返回 false 表示不是從庫,即為主庫) SELECT pg_is_in_recovery();
提升成功后,從庫將成為新的主庫,可接收寫操作。此時(shí)需修改業(yè)務(wù)系統(tǒng)的數(shù)據(jù)庫連接地址,將原來的主庫地址(5432端口)改為新主庫地址(5433端口),待原主庫修復(fù)后,可將其配置為新主庫的從庫,恢復(fù)主從架構(gòu)。
3.3 性能優(yōu)化建議(生產(chǎn)環(huán)境必備)
- 優(yōu)化 WAL 日志配置:將
wal\_buffers設(shè)為 16MB(默認(rèn)較?。瑴p少 WAL 日志寫入磁盤的頻率,提升主庫寫性能; - 限制從庫讀壓力:從庫開啟熱備后,可通過
max\_connections限制只讀連接數(shù),避免從庫因讀壓力過大影響同步效率; - 數(shù)據(jù)掛載優(yōu)化:生產(chǎn)環(huán)境建議使用 SSD 磁盤掛載數(shù)據(jù)目錄,提升磁盤 I/O 速度,減少同步延遲;
- 定期清理 WAL 日志:主庫的 WAL 日志歸檔目錄會(huì)不斷增大,需定期清理過期日志(如保留最近7天的日志),避免磁盤占滿。
3.4 常見問題排查(避坑指南)
問題1:從庫無法連接主庫,日志提示“connection refused”
原因:主從容器未在同一網(wǎng)絡(luò)、主庫端口未開放、主庫 pg\_hba\.conf 配置錯(cuò)誤。
解決:
- 確認(rèn)主從容器都加入
pg\_network網(wǎng)絡(luò)(docker network inspect pg\_network); - 驗(yàn)證主庫端口是否開放(
docker exec \-it pg\-master netstat \-tuln \| grep 5432); - 檢查主庫
pg\_hba\.conf中,復(fù)制用戶的訪問權(quán)限是否正確(網(wǎng)段是否匹配)。
問題2:從庫同步失敗,日志提示“could not receive data from WAL stream”
原因:主庫 WAL 日志被清理(wal\_keep\_segments 設(shè)置過小)、主從版本不一致、復(fù)制用戶權(quán)限不足。
解決:
- 增大主庫
wal\_keep\_segments的值(如設(shè)為 128),重啟主庫; - 確保主從使用相同版本的 Pgsql 鏡像(本文均使用 14 版本);
- 驗(yàn)證復(fù)制用戶(replica)是否具備
replication權(quán)限(\\du查看)。
問題3:主庫寫操作正常,從庫數(shù)據(jù)同步延遲過大
原因:網(wǎng)絡(luò)延遲過高、從庫性能不足、主庫寫壓力過大。
解決:
- 確保主從服務(wù)器在同一局域網(wǎng),減少網(wǎng)絡(luò)延遲;
- 提升從庫服務(wù)器配置(CPU、內(nèi)存),優(yōu)化從庫
postgresql\.conf配置; - 分擔(dān)主庫寫壓力,避免批量寫入操作集中執(zhí)行。
四、總結(jié):Docker + Pgsql 主從復(fù)制的核心價(jià)值與實(shí)踐建議
Docker 下配置 Pgsql 主從復(fù)制,核心優(yōu)勢(shì)在于“快速部署、環(huán)境隔離、配置靈活”,無需復(fù)雜的系統(tǒng)環(huán)境配置,通過 Docker Compose 即可快速搭建主從架構(gòu),大幅降低運(yùn)維成本。主從復(fù)制不僅能解決 Pgsql 單點(diǎn)故障問題,還能實(shí)現(xiàn)數(shù)據(jù)備份和讀寫分離,提升系統(tǒng)可用性和并發(fā)處理能力,是生產(chǎn)環(huán)境中 Pgsql 部署的必備方案。
結(jié)合本文的實(shí)操步驟,總結(jié)以下實(shí)踐建議:
- 測(cè)試環(huán)境可使用本文的基礎(chǔ)配置(異步復(fù)制、trust 認(rèn)證),生產(chǎn)環(huán)境需修改為復(fù)雜密碼、md5 認(rèn)證、同步復(fù)制(或一主多從),提升安全性和數(shù)據(jù)一致性;
- 定期備份主庫數(shù)據(jù)(除了主從同步,建議每周執(zhí)行一次全量備份),避免極端情況下的數(shù)據(jù)丟失;
- 定期監(jiān)控主從復(fù)制狀態(tài)(通過
pg\_stat\_replication和容器日志),及時(shí)發(fā)現(xiàn)并解決同步異常; - 若業(yè)務(wù)量較大,可搭建“一主多從”架構(gòu),多個(gè)從庫分擔(dān)讀壓力,進(jìn)一步提升系統(tǒng)并發(fā)能力。
本文從基礎(chǔ)配置到進(jìn)階拓展,詳細(xì)講解了 Docker 下 Pgsql 主從復(fù)制的全過程,所有示例代碼均可直接實(shí)操,適合新手和運(yùn)維人員參考。實(shí)際生產(chǎn)環(huán)境中,可根據(jù)業(yè)務(wù)需求靈活調(diào)整配置,讓 Pgsql 主從架構(gòu)更好地服務(wù)于業(yè)務(wù),保障數(shù)據(jù)安全和系統(tǒng)穩(wěn)定。
以上就是Docker下配置PostgreSQL主從復(fù)制的詳細(xì)步驟指南的詳細(xì)內(nèi)容,更多關(guān)于Docker配置PostgreSQL主從復(fù)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
docker的iptables策略詳解和用戶自定義策略的添加方式
在Docker環(huán)境下,直接修改iptables以允許特定主機(jī)訪問指定端口時(shí),需要考慮Docker自身的iptables規(guī)則,Docker通過修改nat表的PREROUTING鏈和filter表的FORWARD鏈來處理外部對(duì)Docker容器的訪問,繞過了filter表的INPUT鏈2024-10-10
詳解docker進(jìn)行數(shù)據(jù)掛載的三種模式
Docker?提供了三種方式將數(shù)據(jù)從宿主機(jī)掛載到?Docker容器中:?volumes、bind?mounts、tmpfs?,這篇文章主要介紹了docker進(jìn)行數(shù)據(jù)掛載的三種模式,需要的朋友可以參考下2022-05-05
Docker使用編寫dockerfile啟動(dòng)node.js應(yīng)用
這篇文章主要介紹了Docker使用編寫dockerfile啟動(dòng)node.js應(yīng)用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
docker之如何設(shè)置日志文件大小及個(gè)數(shù)
這篇文章主要介紹了docker之如何設(shè)置日志文件大小及個(gè)數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
Linux下docker安裝mysql8并配置遠(yuǎn)程連接
本文主要介紹了Linux下docker安裝mysql8并配置遠(yuǎn)程連接,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Intellij IDEA快速實(shí)現(xiàn)Docker鏡像部署的方法步驟
本文主要介紹了Intellij IDEA快速實(shí)現(xiàn)Docker鏡像部署的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09

