PostgreSQL流復(fù)制(主從復(fù)制)詳細(xì)教程
一、流復(fù)制簡(jiǎn)介
在數(shù)據(jù)庫(kù)業(yè)務(wù)中,為了防止單點(diǎn)故障的發(fā)生、提高數(shù)據(jù)庫(kù)服務(wù)器的服務(wù)性能,一般都會(huì)采用「主從復(fù)制」集群來(lái)保障數(shù)據(jù)庫(kù)中數(shù)據(jù)的高可用。
而在 PostgreSQL 中,主從復(fù)制有其特定的技術(shù)名稱 ——流復(fù)制(Streaming Replication)。主從復(fù)制是所有數(shù)據(jù)庫(kù)主從架構(gòu)的統(tǒng)稱,而流復(fù)制是 PostgreSQL 實(shí)現(xiàn)主從復(fù)制的核心技術(shù),也是最常用的方式,特點(diǎn)是從庫(kù)實(shí)時(shí)(流式)接收主庫(kù)的 WAL 日志并應(yīng)用,延遲較低。PostgreSQL 中更推薦用 “主庫(kù)(Primary)” 和 “從庫(kù)(Standby)” 替代 “Master/Slave” 的說法。
此外,PostgreSQL 的流復(fù)制還可細(xì)分:
- 異步流復(fù)制(默認(rèn)):主庫(kù)寫入數(shù)據(jù)后無(wú)需等待從庫(kù)確認(rèn),性能高,可能有少量延遲。
- 同步流復(fù)制:主庫(kù)寫入數(shù)據(jù)后,必須等待從庫(kù)確認(rèn)已接收 WAL 日志才返回成功,安全性高但性能略低。
二、流復(fù)制原理與步驟
PostgreSQL 流復(fù)制的核心依賴于其WAL(Write-Ahead Logging,預(yù)寫日志)機(jī)制,這是PostgreSQL 保證數(shù)據(jù)一致性的基礎(chǔ),也是復(fù)制的 “數(shù)據(jù)源”。
1. WAL 日志的作用
- 主庫(kù)執(zhí)行任何數(shù)據(jù)修改操作(增刪改)時(shí),會(huì)先將操作記錄寫入 WAL 日志(類似 “操作日志”,相當(dāng)于MySQL中的binlog),再更新實(shí)際數(shù)據(jù)文件。
- 即使主庫(kù)突然崩潰,重啟后可通過 WAL 日志恢復(fù)未完成的操作,保證數(shù)據(jù)一致性。
- 對(duì)復(fù)制而言:WAL 日志是主從數(shù)據(jù)同步的 “橋梁”—— 從庫(kù)通過獲取并應(yīng)用主庫(kù)的 WAL 日志,即可復(fù)現(xiàn)主庫(kù)的所有操作,保持?jǐn)?shù)據(jù)一致。
2. 流復(fù)制的核心進(jìn)程
主庫(kù)(Primary)
wal_sender進(jìn)程:當(dāng)從庫(kù)連接主庫(kù)時(shí),主庫(kù)會(huì)啟動(dòng)wal_sender進(jìn)程,負(fù)責(zé)將 WAL 日志實(shí)時(shí)發(fā)送給從庫(kù)。
從庫(kù)(Standby)
wal_receiver 進(jìn)程:從庫(kù)啟動(dòng)后,會(huì)啟動(dòng) wal_receiver 進(jìn)程,主動(dòng)連接主庫(kù)wal_sender,接收 WAL 日志并寫入從庫(kù)的 WAL 文件。
startup 進(jìn)程:負(fù)責(zé)讀取本地接收的 WAL 日志,并將日志中的操作應(yīng)用到從庫(kù)的數(shù)據(jù)文件中,最終實(shí)現(xiàn)數(shù)據(jù)同步。
3.流復(fù)制的同步步驟
1.主庫(kù)每執(zhí)行一次數(shù)據(jù)修改(如插入、更新),都會(huì)生成新的 WAL 記錄并寫入本地 WAL 文件。
2.從庫(kù)啟動(dòng)后,wal_receiver 進(jìn)程根據(jù) postgresql.conf 中 primary_conninfo 的配置(主庫(kù) IP、復(fù)制用戶、密碼),主動(dòng)連接主庫(kù)的 5432 端口。
3.主庫(kù)驗(yàn)證從庫(kù)的連接(通過 pg_hba.conf 配置的權(quán)限)后,啟動(dòng) wal_sender 進(jìn)程,開始向從庫(kù)實(shí)時(shí)流式傳輸新生成的 WAL 日志(從備份結(jié)束的位置開始,避免重復(fù)傳輸)。
4.從庫(kù)的 wal_receiver 接收 WAL 日志后,寫入本地的 WAL 文件。從庫(kù)的 startup 進(jìn)程讀取本地 WAL 文件,將日志中的操作逐條應(yīng)用到從庫(kù)的數(shù)據(jù)文件中,最終實(shí)現(xiàn)與主庫(kù)的數(shù)據(jù)一致。
三、流復(fù)制的實(shí)現(xiàn)
- 操作系統(tǒng):CentOS7
- PostgreSQL版本:psql (PostgreSQL) 13.22
- 主庫(kù)IP:11.0.0.136
- 從庫(kù)IP:11.0.0.137
1、準(zhǔn)備工作
# 1.關(guān)閉防火墻
systemctl stop firewalld
systemctl disable firewalld
# 或者開放5432端口
firewall-cmd --add-port=5432/tcp --permanent
firewall-cmd --reload
# 2.關(guān)閉SELINUX
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
# 3.同步時(shí)間
ntpdate ntp.ntsc.ac.cn
# 4.確保你的YUM源可用2、安裝PostgreSQL(主從庫(kù)都安裝)
進(jìn)入官網(wǎng):https://www.postgresql.org/download/

選擇相應(yīng)操作系統(tǒng)和版本

# 1、安裝 PostgreSQL 官方的 YUM 源配置包 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm # 2、安裝 PostgreSQL 的服務(wù)器端程序 yum install -y postgresql13-server # 3、初始化 PostgreSQL 的數(shù)據(jù)庫(kù)集群 /usr/pgsql-13/bin/postgresql-13-setup initdb # 4、啟動(dòng) PostgreSQL 并設(shè)置開機(jī)自啟 systemctl enable postgresql-13 systemctl start postgresql-13 # 5、驗(yàn)證安裝 psql --version
3、主庫(kù)配置
1、修改主庫(kù)核心配置
vim /var/lib/pgsql/13/data/postgresql.conf # 添加以下內(nèi)容 ----------------------------------------------------------------------------------------- # 允許所有IP連接(生產(chǎn)環(huán)境可指定從庫(kù)IP) listen_addresses = '*' # WAL日志級(jí)別(至少為replica才能支持流復(fù)制) wal_level = replica # 允許的最大復(fù)制連接數(shù)(至少1,建議3-5) max_wal_senders = 3 # 保留的WAL日志大?。ǚ乐箯膸?kù)同步時(shí)WAL被刪除,建議1GB) wal_keep_size = 1GB # 開啟歸檔模式(流復(fù)制依賴歸檔) archive_mode = on # 歸檔命令(暫時(shí)用/bin/true表示不實(shí)際歸檔,僅開啟模式) archive_command = '/bin/true' -----------------------------------------------------------------------------------------
2、配置主庫(kù)訪問控制
vim /var/lib/pgsql/13/data/pg_hba.conf # 添加以下內(nèi)容 ----------------------------------------------------------------------------------------- # 允許從庫(kù)(11.0.0.137)通過 replica 用戶進(jìn)行復(fù)制(md5 密碼驗(yàn)證) # host 數(shù)據(jù)庫(kù) / 功能 用戶名 從庫(kù)IP 認(rèn)證方式 host replication replica 11.0.0.137/32 md5 -----------------------------------------------------------------------------------------
3、創(chuàng)建復(fù)制專用用戶(replica)
# 1、切換到postgres用戶 su - postgres # 2、進(jìn)入數(shù)據(jù)庫(kù) psql
# 3、創(chuàng)建復(fù)制專用用戶,設(shè)置密碼 CREATE ROLE replica REPLICATION LOGIN ENCRYPTED PASSWORD 'peidongqing@123'; # 4、 退出psql \q # 5、退出postgres用戶 exit
# 6、重啟主庫(kù) systemctl restart postgresql-13
4、從庫(kù)配置
1、停止從庫(kù)服務(wù)并清空默認(rèn)數(shù)據(jù)
從庫(kù)需使用主庫(kù)的備份數(shù)據(jù)初始化,因此先刪除默認(rèn)數(shù)據(jù)
# 停止從庫(kù)PostgreSQL服務(wù) systemctl stop postgresql-13 # 清空從庫(kù)數(shù)據(jù)目錄(默認(rèn)路徑) rm -rf /var/lib/pgsql/13/data/*
2、從主庫(kù)同步基礎(chǔ)數(shù)據(jù)
# 切換到postgres用戶(確保權(quán)限正確) su - postgres # 執(zhí)行基礎(chǔ)備份(從主庫(kù)11.0.0.136同步數(shù)據(jù)到從庫(kù)) pg_basebackup -h 11.0.0.136 -U replica -D /var/lib/pgsql/13/data/ -Fp -Xs -P
執(zhí)行后會(huì)提示輸入密碼,輸入設(shè)置的replica用戶密碼peidongqing@123,等待備份完成
-h 11.0.0.136:主庫(kù) IP-U replica:復(fù)制用戶-D:從庫(kù)數(shù)據(jù)目錄(需與主庫(kù)一致)-Fp:輸出格式為原始文件(非壓縮)-Xs:備份時(shí)自動(dòng)復(fù)制 WAL 日志(確保數(shù)據(jù)一致性)-P:顯示進(jìn)度
3、配置從庫(kù)連接主庫(kù)
# 切換到root用戶,編輯從庫(kù)配置文件 vim /var/lib/pgsql/13/data/postgresql.conf ----------------------------------------------------------------------------------------- # 從庫(kù)連接主庫(kù)的信息 primary_conninfo = 'host=11.0.0.136 port=5432 user=replica password=peidongqing@123' # 允許從庫(kù)只讀查詢 hot_standby = on -----------------------------------------------------------------------------------------
4、創(chuàng)建standby.signal文件,啟用從庫(kù)模式
# 切換到postgres用戶,創(chuàng)建信號(hào)文件 su - postgres touch /var/lib/pgsql/13/data/standby.signal # 退出postgres用戶 exit # 啟動(dòng)從庫(kù)服務(wù) systemctl start postgresql-13 systemctl enable postgresql-13
5、驗(yàn)證主從復(fù)制
主從驗(yàn)證均是通過postgres用戶登錄數(shù)據(jù)庫(kù)驗(yàn)證
# 切換 postgres 用戶 su - postgres # 進(jìn)入數(shù)據(jù)庫(kù) psql
1、連接狀態(tài)驗(yàn)證
主庫(kù)
SELECT client_addr, state FROM pg_stat_replication; # 成功輸出 client_addr | state -------------+----------- 11.0.0.137 | streaming (1 行記錄)
從庫(kù)
SELECT status FROM pg_stat_wal_receiver; # 成功輸出 status ----------- streaming (1 行記錄)
2、數(shù)據(jù)同步驗(yàn)證
主庫(kù)
# 創(chuàng)建數(shù)據(jù)表 CREATE TABLE test_replica (id int); # 插入數(shù)據(jù) INSERT INTO test_replica VALUES (11111);
從庫(kù)
SELECT * FROM test_replica;
# 成功輸出
id
---------
111111
(1 行記錄)總結(jié)
通過以上步驟,PostgreSQL 13 一主一從流復(fù)制架構(gòu)已搭建完成:
- 主庫(kù)(11.0.0.136)負(fù)責(zé)寫入數(shù)據(jù),并通過 WAL 日志同步到從庫(kù)。
- 從庫(kù)(11.0.0.137)實(shí)時(shí)接收主庫(kù)日志,保持?jǐn)?shù)據(jù)一致,支持只讀查詢。
- 若主庫(kù)故障,可手動(dòng)將從庫(kù)提升為主庫(kù)。
到此這篇關(guān)于PostgreSQL流復(fù)制(主從復(fù)制)詳細(xì)教程的文章就介紹到這了,更多相關(guān)PostgreSQL流復(fù)制(主從復(fù)制)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Postgresql刪除數(shù)據(jù)庫(kù)表中重復(fù)數(shù)據(jù)的幾種方法詳解
本文詳細(xì)講解了Postgresql刪除數(shù)據(jù)庫(kù)表中重復(fù)數(shù)據(jù)的幾種方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
用PostgreSQL數(shù)據(jù)庫(kù)做地理位置app應(yīng)用
項(xiàng)目中用到了postgreSQL中的earthdistance()函數(shù)功能計(jì)算地球上兩點(diǎn)之間的距離,中文的資料太少了,我找到了一篇 英文的、講的很好的文章,特此翻譯,希望能夠幫助到以后用到earthdistance的同學(xué)2014-03-03
關(guān)于PostgreSQL截取某個(gè)字段中的部分內(nèi)容進(jìn)行排序的問題
這篇文章主要介紹了PostgreSQL截取某個(gè)字段中的部分內(nèi)容進(jìn)行排序,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
PostgreSQL事務(wù)回卷實(shí)戰(zhàn)案例詳析
前段時(shí)間在公司小范圍做了一個(gè)關(guān)于PG事務(wù)實(shí)現(xiàn)的講座,最后總結(jié)了一個(gè)摘要性的東西,分享一下,這篇文章主要給大家介紹了關(guān)于PostgreSQL事務(wù)回卷實(shí)戰(zhàn)案例的相關(guān)資料,需要的朋友可以參考下2022-03-03
PostgreSQL教程(三):表的繼承和分區(qū)表詳解
這篇文章主要介紹了PostgreSQL教程(三):表的繼承和分區(qū)表詳解,本文講解了多表繼承、 繼承和權(quán)限、什么是分區(qū)表、分區(qū)表實(shí)現(xiàn)、分區(qū)和約束排除等內(nèi)容,需要的朋友可以參考下2015-05-05
PostgreSQL數(shù)據(jù)庫(kù)如何定期清理歸檔(pg_wal)日志
在?般的?產(chǎn)環(huán)境中,數(shù)據(jù)庫(kù)都需要開啟歸檔模式,下面這篇文章主要給大家介紹了關(guān)于PostgreSQL數(shù)據(jù)庫(kù)如何定期清理歸檔(pg_wal)日志的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05
PostgreSQL數(shù)據(jù)庫(kù)儲(chǔ)存空間不足的解決方案
在使用 PostgreSQL 數(shù)據(jù)庫(kù)時(shí),可能會(huì)遇到存儲(chǔ)空間不足的問題,這個(gè)問題不僅會(huì)影響數(shù)據(jù)庫(kù)的正常運(yùn)行,還可能導(dǎo)致數(shù)據(jù)丟失或應(yīng)用程序出現(xiàn)故障,因此,了解如何應(yīng)對(duì)這種情況至關(guān)重要,所以本文給大家就介紹了PostgreSQL數(shù)據(jù)庫(kù)儲(chǔ)存空間不足的解決方案,需要的朋友可以參考下2024-07-07

