你需要經(jīng)常使用邏輯復(fù)制嗎?你擔(dān)心其給主用數(shù)據(jù)庫帶來的壓力嗎?
復(fù)制的背景 總體而言,PostgreSQL 支持兩種主要的復(fù)制類型:流式/物理復(fù)制和邏輯復(fù)制。預(yù)寫式日志可以通過連接流式傳輸整組的物理文件,并將整個(gè)數(shù)據(jù)庫在磁盤上進(jìn)行重放。邏輯復(fù)制提供了一種更細(xì)粒度的方法,您可以指定要復(fù)制到遠(yuǎn)程服務(wù)器的單個(gè)數(shù)據(jù)庫對(duì)象(例如表,甚至特定行)。
PostgreSQL 中的備用服務(wù)器是通過對(duì)主服務(wù)器進(jìn)行基礎(chǔ)備份,并持續(xù)應(yīng)用在主服務(wù)器上所做的所有更改來創(chuàng)建的。熱備服務(wù)器是指可以提升為主服務(wù)器的備用服務(wù)器。PostgreSQL 將修改保存在 WAL(預(yù)寫日志)記錄中,并將它們從主服務(wù)器復(fù)制到備用服務(wù)器。如果備用服務(wù)器需要表中的行,則配置參數(shù) hot_standby_feeedback
可防止表行過早地從主服務(wù)器中刪除。
從備用數(shù)據(jù)庫進(jìn)行復(fù)制的示例設(shè)置 假設(shè)我們有三臺(tái)不同的 PostgreSQL 服務(wù)器,用于管理一家全球物流公司的庫存,其倉庫遍布全球。主服務(wù)器存儲(chǔ)倉庫和庫存信息,備用服務(wù)器是一臺(tái)物理復(fù)制的高可用服務(wù)器,第三臺(tái)服務(wù)器用于獲取特定的更改以用于分析報(bào)告。
主機(jī) 在主實(shí)例中,您需要具有復(fù)制權(quán)限的用戶。在本例中,我創(chuàng)建了一個(gè)用戶,用于將更改流式傳輸?shù)絺溆脤?shí)例,并創(chuàng)建了另一個(gè)用戶,用于將更改發(fā)布到訂閱實(shí)例。
CREATE ROLE repuser WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'somestrongpassword' ; CREATE ROLE pubuser WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'differentstrongpassword' ;
接下來,創(chuàng)建一個(gè)物理復(fù)制槽,用于將更改從主服務(wù)器復(fù)制到備用服務(wù)器。嚴(yán)格來說,這不是必需的,但實(shí)際上確實(shí)需要。如果沒有物理復(fù)制槽,任何一個(gè)節(jié)點(diǎn)重啟或連接斷開都會(huì)中斷復(fù)制過程:
SELECT pg_create_physical_replication_slot( 'hot_standby_1' );
假定我們只關(guān)心上海倉庫的庫存,其代碼為 SH
。在主服務(wù)器上,我們將為 inventory
表所依賴的表創(chuàng)建一個(gè)發(fā)布 inventory_requirements
,并創(chuàng)建另一個(gè)名為 inventory_sh_pub
的發(fā)布:
表:warehouses (倉庫)
表:inventory (庫存)
CREATE PUBLICATION inventory_requirements_pub FOR TABLE regions, countries, warehouses, products; CREATE PUBLICATION inventory_sh_pub FOR TABLE inventory WHERE (warehouse = 'SH' ); GRANT SELECT ON TABLE regions, countries, warehouses, products, inventory TO pubuser;
備機(jī) 此時(shí),可以創(chuàng)建備用實(shí)例了。我們將使用 pg_basebackup
來初始化備用實(shí)例?;謴?fù)備機(jī)的數(shù)據(jù)目錄后,您需要編輯其中的 postgresql.conf
,并確保其具有一些參數(shù)( 如此處所述 ):
# Provide feedback to the primary or upstream standby about # queries currently executing on this standby hot_standby_feedback = on # Use the physical replication slot we created previously primary_slot_name = 'hot_standby_1' hot_standby = on archive_mode = on # If level is changed to below logical, slots will be dropped wal_level = logical # standby streams changes from the primary primary_conn_info = 'host=127.0.0.1 port=5432 user=repuser password=somestrongpassword' max_wal_senders = 10 # max number of walsender processes max_replication_slots = 10 # max number of replication slots # If an upstream standby server is promoted to become the new # primary, downstream servers will continue to stream from # the new primary recovery_target_timeline = 'latest'
連接到該備用服務(wù)器,可以確認(rèn)它處于只讀模式:
SELECT pg_is_in_recovery(); pg_is_in_recovery ------------------- t
此時(shí)我們有:
? 主實(shí)例通過物理復(fù)制槽同步到一個(gè)備用實(shí)例,并設(shè)置了 hot_standby_feedback = on
? 名為 inventory_requirements_pub
和 inventory_sh_pub
的發(fā)布 備機(jī)上的邏輯副本 現(xiàn)在我們可以登錄用于分析報(bào)告的 PostgreSQL 實(shí)例,訂閱備用數(shù)據(jù)庫的更改。在 PostgreSQL 16 以前的版本中,該操作會(huì)失敗。
邏輯復(fù)制的一大優(yōu)勢(shì)是,您可以訂閱不同版本的 PostgreSQL 服務(wù)器的變更!這為您在使用不同版本 PostgreSQL 的應(yīng)用程序時(shí)提供了極大的靈活性。
CREATE SUBSCRIPTION inventory_requirements_sub CONNECTION 'dbname=inventory host=127.0.0.1 port=5434 user=pubuser password=differentstrongpassword' PUBLICATION inventory_requirements_pub; CREATE SUBSCRIPTION inventory_sh_sub CONNECTION 'dbname=inventory host=127.0.0.1 port=5434 user=pubuser password=differentstrongpassword' PUBLICATION inventory_sh_pub;
如果主服務(wù)器空閑,該操作會(huì)掛起。這是因?yàn)閭溆梅?wù)器正在等待來自主服務(wù)器的信息。您可以通過在主服務(wù)器上調(diào)用新函數(shù) pg_log_standby_snapshot()
,來加快創(chuàng)建這些對(duì)象的速度。在本例中,我們會(huì)調(diào)用兩次,因?yàn)槲覀円獎(jiǎng)?chuàng)建兩個(gè)訂閱。
SELECT pg_log_standby_snapshot(); pg_log_standby_snapshot ------------------------- 0 / 23000180
這樣允許副本繼續(xù)運(yùn)行,并生成類似這樣的消息,告訴我們已在備用服務(wù)器上創(chuàng)建了一個(gè)復(fù)制槽。
NOTICE : created replication slot "inventory_requirements_sub" on publisher CREATE SUBSCRIPTION
我們可以在備用服務(wù)器上的 pg_stat_replication
系統(tǒng)視圖中驗(yàn)證這一點(diǎn)。
SELECT pid, application_name, state, sync_state FROM pg_stat_replication; pid | application_name | state | sync_state -------+----------------------------+-----------+------------ 23265 | inventory_sh_sub | streaming | async 23251 | inventory_requirements_sub | streaming | async ( 2 rows )
一旦更改同步到了備用服務(wù)器,它們就會(huì)被同步到下游的報(bào)告服務(wù)器,我們將在那里看到這些更改。請(qǐng)注意,只有 SH
倉庫的記錄會(huì)被同步過來。
SELECT * FROM inventory ORDER BY product_id; warehouse | product_id | quantity -----------+------------+---------- SH | 11 | 7 SH | 13 | 13 SH | 15 | 18 SH | 22 | 15 SH | 24 | 20
如果需要,我們還可以在這里為不同的區(qū)域和倉庫創(chuàng)建多個(gè)邏輯副本。
閱讀原文:原文鏈接
該文章在 2025/7/1 22:50:17 編輯過