pg日志傳送后備服務(wù)器

連續(xù)歸檔可以用來(lái)創(chuàng)建一個(gè)高可用(HA)集群配置, 其中有一個(gè)或多個(gè)后備服務(wù)器隨時(shí)準(zhǔn)備在主服務(wù)器失效時(shí)接管操作。 這種能力被廣泛地稱(chēng)為溫備或日志傳送。

主服務(wù)器和后備服務(wù)器一起工作來(lái)提供這種能力,但這些服務(wù)器只是松散地組織在一起。主服務(wù)器在連續(xù)歸檔模式下操作, 而每一個(gè)后備服務(wù)器在連續(xù)恢復(fù)模式下操作并且從主服務(wù)器讀取WAL文件。 要啟用這種能力不需要對(duì)數(shù)據(jù)庫(kù)表做任何改動(dòng), 因此它相對(duì)于其他復(fù)制方案降低了管理開(kāi)銷(xiāo)。 這種配置對(duì)主服務(wù)器的性能影響也相對(duì)較低。

直接從一個(gè)數(shù)據(jù)庫(kù)服務(wù)器移動(dòng)WAL記錄到另一臺(tái)服務(wù)器通常被描述為日志傳送。? PostgreSQL通過(guò)一次一文件(WAL段) 的WAL記錄傳輸實(shí)現(xiàn)了基于文件的日志傳送。不管 WAL 文件(16 MB)被送到一個(gè)臨近的系統(tǒng)、同一站點(diǎn)的另一個(gè)系統(tǒng)或是在地球遙遠(yuǎn)的另一端的一個(gè)系統(tǒng)上,它都可以在任何距離上被簡(jiǎn)單和便宜地傳送。這種技術(shù)所需的帶寬取根據(jù)主服務(wù)器的事務(wù)率而變化?;谟涗浀娜罩緜魉途哂懈?xì)的粒度并且能夠在網(wǎng)絡(luò)連接上以流的方式增量傳遞WAL的改變。

需要注意的是日志傳送是異步的,即WAL記錄是在事務(wù)提交后才被傳送。 正因?yàn)槿绱?,在一個(gè)窗口期內(nèi)如果主服務(wù)器發(fā)生災(zāi)難性的失效則會(huì)導(dǎo)致數(shù)據(jù)丟失, 還沒(méi)有被傳送的事務(wù)將會(huì)被丟失。 基于文件的日志傳送中這個(gè)數(shù)據(jù)丟失窗口的尺寸可以通過(guò)使用參數(shù) archive_timeout進(jìn)行限制,它可以被設(shè)置成低至數(shù)秒。 但是這樣低的設(shè)置大體上會(huì)增加文件傳送所需的帶寬。 流復(fù)制允許更小的數(shù)據(jù)丟失窗口。

這種配置的恢復(fù)性能是足夠好的,后備服務(wù)器在被激活后通常只有片刻就可以達(dá)到完全可用。 因此,這被稱(chēng)為一種提供高可用性的溫備配置。 從一個(gè)已歸檔的基礎(chǔ)備份恢復(fù)一個(gè)服務(wù)器并且前滾將需要較長(zhǎng)時(shí)間, 因此該技術(shù)只提供了災(zāi)難恢復(fù)的一種方案,而不適合于高可用性。

如果一臺(tái)后備服務(wù)器只有被提升為一臺(tái)主控服務(wù)器后才能被連接, 它被稱(chēng)為一臺(tái)溫后備服務(wù)器, 而一臺(tái)能夠接受連接并且提供只讀查詢(xún)的后備服務(wù)器被稱(chēng)為一臺(tái) 熱后備服務(wù)器。

規(guī)劃設(shè)計(jì)

創(chuàng)建主服務(wù)器和后備服務(wù)器通常是明智的,因此它們可以盡可能相似, 至少?gòu)臄?shù)據(jù)庫(kù)服務(wù)器的角度來(lái)看是這樣。特別地, 與表空間相關(guān)的路徑名將被未經(jīng)修改地傳遞,因此如果該特性被使用, 主、備服務(wù)器必須對(duì)表空間具有完全相同的掛載路徑。 記住如果CREATE TABLESPACE在主服務(wù)器上被執(zhí)行, 在命令被執(zhí)行前,它所需要的任何新掛載點(diǎn)必須在主服務(wù)器和所有后備服務(wù)器上先創(chuàng)建好。在任何情況下硬件架構(gòu)必須相同,從一個(gè) 32 位系統(tǒng)傳送到一個(gè) 64 位系統(tǒng)將不會(huì)工作。

通常,不能在兩個(gè)運(yùn)行著不同主版本PostgreSQL的服務(wù)器之間傳送日志。PostgreSQL 全球開(kāi)發(fā)組的策略是不在次版本升級(jí)中改變磁盤(pán)格式, 因此在主服務(wù)器和后備服務(wù)器上運(yùn)行不同次版本將會(huì)成功地工作。不過(guò), 在這方面并沒(méi)有提供正式的支持,因此我們建議讓主備服務(wù)器上運(yùn)行的版本盡可能相同當(dāng)升級(jí)到一個(gè)新的次版本時(shí),最安全的策略是先升級(jí)后備服務(wù)器 — 一個(gè)新的次版本發(fā)行更可能兼容從前一個(gè)次版本讀取 WAL 文件

后備服務(wù)器操作(restore_command)

在后備模式中,服務(wù)器持續(xù)地應(yīng)用從主控服務(wù)器接收到的 WAL。 后備服務(wù)器可以從一個(gè) WAL 歸檔(restore_command) 或者通過(guò)一個(gè) TCP 連接直接從主控機(jī)(流復(fù)制)讀取 WAL。 后備服務(wù)器也會(huì)嘗試恢復(fù)在后備集簇的pg_wal目錄中找到的 WAL。 通常在一次數(shù)據(jù)庫(kù)重啟后,后備機(jī)將重播在重啟之前從主控機(jī)流過(guò)來(lái)的 WAL, 但是你也可以在任何時(shí)候手動(dòng)拷貝文件到pg_wal讓它們被重播。

在啟動(dòng)時(shí),后備機(jī)通過(guò)恢復(fù)歸檔位置所有可用的WAL開(kāi)始, 稱(chēng)為restore_command。

1) 一旦重播到達(dá)可用WAL的末尾并且 restore_command失敗,它會(huì)嘗試恢復(fù)pg_wal 目錄中可用的任何WAL。

2) 如果嘗試重試恢復(fù)失敗且流復(fù)制已被配置, 后備機(jī)會(huì)嘗試連接到主服務(wù)器并從在歸檔或pg_wal 中找到的最后一個(gè)可用記錄開(kāi)始流式傳送 WAL。

3) 如果嘗試重試恢復(fù)失敗且沒(méi)有配置流復(fù)制, 或者該連接后斷開(kāi),后備機(jī)返回到步驟 1) 且嘗試再次從歸檔里的文件恢復(fù)。

這種嘗試歸檔、pg_wal和流復(fù)制的循環(huán)會(huì)一直重復(fù)直到服務(wù)器停止或者一個(gè)觸發(fā)器文件觸發(fā)了故障轉(zhuǎn)移。

當(dāng)pg_ctl promote(升主)被運(yùn)行或一個(gè)觸發(fā)器文件被找到 (trigger_file),后備模式會(huì)退出并且服務(wù)器會(huì)切換到普通操作。 在故障轉(zhuǎn)移前,在歸檔或pg_wal中可用的任何WAL將立即被恢復(fù), 但不會(huì)嘗試連接到主控機(jī)。

為后備服務(wù)器準(zhǔn)備主控機(jī)

在主服務(wù)器上設(shè)置連續(xù)歸檔到一個(gè)后備服務(wù)器可訪(fǎng)問(wèn)的歸檔目錄。 如果主服務(wù)器垮掉該歸檔位置應(yīng)當(dāng)是后備服務(wù)器可訪(fǎng)問(wèn)的,可以位于后備服務(wù)器本身或者另一個(gè)可信賴(lài)的服務(wù)器,而不是位于主控服務(wù)器上。

如果使用流復(fù)制,在主服務(wù)器上設(shè)置認(rèn)證來(lái)允許來(lái)自后備服務(wù)器的復(fù)制連接。創(chuàng)建一個(gè)角色并且在pg_hba.conf中提供一個(gè)或多個(gè)數(shù)據(jù)庫(kù)域被設(shè)置為replication的項(xiàng),還要保證在主服務(wù)器配置文件中max_wal_senders設(shè)置足夠大的值。如果使用復(fù)制槽, 請(qǐng)確保max_replication_slots設(shè)置得足夠高。

建立一個(gè)后備服務(wù)器

要建立后備服務(wù)器,恢復(fù)從主服務(wù)器取得的基礎(chǔ)備份。 在后備服務(wù)器的集簇?cái)?shù)據(jù)目錄中創(chuàng)建一個(gè)恢復(fù)命令文件recovery.conf, 并且打開(kāi)standby_mode。將restore_command 設(shè)置為從WAL歸檔中復(fù)制文件的簡(jiǎn)單命令。

如果為了高可用性而建立多個(gè)后備服務(wù)器, 將recovery_target_timeline設(shè)置為latest,使該后備服務(wù)器遵循發(fā)生在故障轉(zhuǎn)移到另一個(gè)后備服務(wù)器之后發(fā)生的時(shí)間線(xiàn)改變。

注意:不要把pg_standby或相似的工具和這里描述的內(nèi)建后備模式一起使用。 如果文件不存在,restore_command應(yīng)該立即返回失敗,該服務(wù)器將再次嘗試該命令。

如果使用流復(fù)制,在primary_conninfo中填入一個(gè)libpq連接字符串,其中包括主機(jī)名(或IP地址)和連接到主服務(wù)器所需的任何附加細(xì)節(jié)(包括認(rèn)證口令)。

如果為高性能而建立后備服務(wù)器,像主服務(wù)器一樣建立WAL歸檔、 連接和認(rèn)證,因?yàn)樵诠收限D(zhuǎn)移后該后備服務(wù)器將作為一個(gè)主服務(wù)器工作。

如果使用一個(gè)WAL歸檔,可以使用archive_cleanup_command 參數(shù)來(lái)移除后備服務(wù)器不再需要的文件,可以最小化 WAL歸檔的尺寸。 pg_archivecleanup工具被特別設(shè)計(jì)為在典型單一后備配置下與 archive_cleanup_command共同使用。 不過(guò)要注意,如果為備份而使用歸檔, 有一些文件即使后備服務(wù)器不再需要也需要保留,至少被用來(lái)從最后一個(gè)基礎(chǔ)備份恢復(fù)。

恢復(fù)命令文件recovery.conf的簡(jiǎn)單例子(認(rèn)證的流復(fù)制,且清理不需要的wal歸檔):

standby_mode = 'on'

primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'

restore_command= 'cp /path/to/archive/%f %p'

archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'

可以有任意數(shù)量的后備服務(wù)器,但如果使用流復(fù)制, 確保主服務(wù)器上max_wal_senders設(shè)置足夠高, 這樣允許它們能同時(shí)連接。

流復(fù)制

流復(fù)制允許一臺(tái)后備服務(wù)器比使用基于文件的日志傳送更能保持最新的狀態(tài)。后備服務(wù)器連接到主服務(wù)器,主服務(wù)器則在WAL記錄產(chǎn)生時(shí)將以流式傳送給后備服務(wù)器而不必等到WAL文件被填充。

默認(rèn)情況下流復(fù)制是異步的, 在這種情況下主服務(wù)器上提交一個(gè)事務(wù)與該變化在后備服務(wù)器上可見(jiàn)之間存在短暫的延遲。這種延遲比基于文件的日志傳送方式中要小得多,在后備服務(wù)器的能力足以跟得上負(fù)載的前提下延遲通常低于一秒。在流復(fù)制中,不需要archive_timeout來(lái)縮減數(shù)據(jù)丟失窗口。

如果使用的流復(fù)制沒(méi)有基于文件的連續(xù)歸檔,該服務(wù)器可能在后備機(jī)收到WAL段之前回收這些舊的WAL段。如果發(fā)生這種情況,后備機(jī)將需要重新從一個(gè)新的基礎(chǔ)備份初始化。通過(guò)設(shè)置wal_keep_segments為一個(gè)足夠高的值來(lái)確保舊的WAL段不會(huì)被太早重用或者為后備機(jī)配置一個(gè)復(fù)制槽,可以避免發(fā)生這種情況。如果設(shè)置了一個(gè)后備機(jī)可以訪(fǎng)問(wèn)的 WAL 歸檔,就不需要這些解決方案,因?yàn)樵摎w檔可以為后備機(jī)保留足夠的段,后備機(jī)總是可以使用該歸檔來(lái)追趕主控機(jī)。

要使用流復(fù)制,建立一個(gè)基于文件的日志傳送后備服務(wù)器。 將一個(gè)基于文件日志傳送后備服務(wù)器轉(zhuǎn)變成流復(fù)制后備服務(wù)器的步驟是把 recovery.conf文件中的primary_conninfo設(shè)置指向主服務(wù)器。設(shè)置主服務(wù)器上的listen_addresses和認(rèn)證選項(xiàng) (見(jiàn)pg_hba.conf),這樣后備服務(wù)器可以連接到主服務(wù)器上的偽數(shù)據(jù)庫(kù) replication。

在支持 keepalive 套接字選項(xiàng)的系統(tǒng)上,設(shè)置 tcp_keepalives_idle、 tcp_keepalives_interval和 tcp_keepalives_count 有助于主服務(wù)器迅速地注意到一個(gè)斷開(kāi)的連接。

設(shè)置來(lái)自后備服務(wù)器的并發(fā)連接的最大數(shù)目 (詳見(jiàn)max_wal_senders)。

當(dāng)后備服務(wù)器被啟動(dòng)并且primary_conninfo正確設(shè)置, 后備服務(wù)器將在重放完歸檔中所有可用的 WAL 文件之后連接到主服務(wù)器。 如果連接被成功建立,你將在后備服務(wù)器中看到一個(gè)walreceiver進(jìn)程, 并且在主服務(wù)器中有一個(gè)相應(yīng)的walsender進(jìn)程。

1) 認(rèn)證

設(shè)置好用于復(fù)制的訪(fǎng)問(wèn)權(quán)限非常重要,這樣只有受信的用戶(hù)可以讀取 WAL 流, 因?yàn)楹苋菀讖?WAL 流中抽取出需要特權(quán)才能訪(fǎng)問(wèn)的信息。 后備服務(wù)器必須作為一個(gè)超級(jí)用戶(hù)或一個(gè)具有REPLICATION 特權(quán)的賬戶(hù)向主服務(wù)器認(rèn)證。我們推薦為復(fù)制創(chuàng)建一個(gè)專(zhuān)用的具有 REPLICATION和LOGIN特權(quán)的用戶(hù)賬戶(hù)。 雖然REPLICATION特權(quán)給出了非常高的權(quán)限, 但它不允許用戶(hù)修改主系統(tǒng)上的任何數(shù)據(jù),而SUPERUSER特權(quán)則可以。

復(fù)制的客戶(hù)端認(rèn)證由一個(gè)在database域中指定replication的pg_hba.conf記錄控制。如果后備服務(wù)器運(yùn)行在主機(jī) IP 192.168.1.100 并且用于復(fù)制的賬戶(hù)名為foo,管理員可以在主服務(wù)器上向 pg_hba.conf文件增加下列行:

# 允許來(lái)自 192.168.1.100 的用戶(hù) "foo" 在提供了正確的口令時(shí)作為一個(gè)

# 復(fù)制后備機(jī)連接到主控機(jī)。

# TYPE? DATABASE? ? ? ? USER? ? ? ? ? ? ADDRESS? ? ? ? ? ? ? ? METHOD

host? ? replication? ? foo? ? ? ? ? ? 192.168.1.100/32? ? ? ? md5

主服務(wù)器的主機(jī)名和端口號(hào)、連接用戶(hù)名和口令在recovery.conf 文件中指定。在后備服務(wù)器上還可以在~/.pgpass文件中設(shè)置口令 (在database域中指定replication)。如果主服務(wù)器運(yùn)行在主機(jī) IP 192.168.1.50、端口 5432上,用于復(fù)制的賬戶(hù)名是foo, 并且口令為foopass,管理員可以在后備服務(wù)器的 recovery.conf文件中增加下列行:

# 后備機(jī)要連接到的主控機(jī)運(yùn)行在主機(jī) 192.168.1.50 上,

# 端口號(hào)是 5432,連接所用的用戶(hù)名是 "foo",口令是 "foopass"。

primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'

2) 監(jiān)控

流復(fù)制的一個(gè)重要健康指標(biāo)是在主服務(wù)器上產(chǎn)生但還沒(méi)有在后備服務(wù)器上應(yīng)用的 WAL 記錄數(shù)。 可以通過(guò)比較主服務(wù)器上的當(dāng)前 WAL寫(xiě)位置和后備服務(wù)器接收到的最后一個(gè) WAL位置來(lái)計(jì)算這個(gè)滯后量。 這些位置分別可以用主服務(wù)器上的pg_current_wal_lsn和后備服務(wù)器上的 pg_last_wal_receive_lsn來(lái)檢索 。 后備服務(wù)器的最后WAL接收位置也被顯示在 WAL 接收者進(jìn)程的進(jìn)程狀態(tài)中, 可以使用ps命令查看顯示的狀態(tài)。

可以通過(guò)pg_stat_replication 視圖檢索 WAL 發(fā)送者進(jìn)程的列表。pg_current_wal_lsn 與視圖的sent_lsn域之間的巨大差異表示主服務(wù)器承受著巨大的負(fù)載, 而sent_lsn和后備服務(wù)器上pg_last_wal_receive_lsn 之間的差異可能表示網(wǎng)絡(luò)延遲或者后備服務(wù)器正承受著巨大的負(fù)載。

復(fù)制槽

復(fù)制槽提供了一種自動(dòng)化的方法來(lái)確保主控機(jī)在所有的后備機(jī)收到 WAL 段 之前不會(huì)移除它們,并且主控機(jī)也不會(huì)移除可能導(dǎo)致 恢復(fù)沖突的行,即使后備機(jī)斷開(kāi)也是如此。

作為復(fù)制槽的替代,也可以使用wal_keep_segments 阻止移除舊的 WAL 段,或者使用archive_command 把段保存在一個(gè)歸檔中。不過(guò),這些方法常常會(huì)導(dǎo)致保留的 WAL 段比需要的 更多,而復(fù)制槽只保留已知所需要的段數(shù)量。這些方法的一個(gè)優(yōu)點(diǎn)是它們?yōu)?pg_wal的空間需求提供了界限,但目前使用復(fù)制槽無(wú)法做到。

類(lèi)似地,hot_standby_feedback和 vacuum_defer_cleanup_age保護(hù)了相關(guān)行不被 vacuum 移除,但是前者在后備機(jī)斷開(kāi)期間無(wú)法提供保護(hù),而后者則需要被設(shè)置為一個(gè)很高 的值以提供足夠的保護(hù)。復(fù)制槽克服了這些缺點(diǎn)。

1) 查詢(xún)和操縱復(fù)制槽

每個(gè)復(fù)制槽都有一個(gè)名字,名字可以包含小寫(xiě)字母、數(shù)字和下劃線(xiàn)字符。

已有的復(fù)制槽和它們的狀態(tài)可以在 pg_replication_slots 視圖中看到。

槽可以通過(guò)流復(fù)制協(xié)議 或者 SQL 函數(shù)創(chuàng)建并且移除。

2) 配置實(shí)例

可以這樣創(chuàng)建一個(gè)復(fù)制槽:

postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');

? slot_name? | lsn

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

node_a_slot |

postgres=# SELECT * FROM pg_replication_slots;

? slot_name? | slot_type | datoid | database | active | xmin | restart_lsn | confirmed_flush_lsn

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

node_a_slot | physical? |? ? ? |? ? | f? |? ? |? ? ? |

(1 row)

要配置后備機(jī)使用這個(gè)槽,在后備機(jī)的recovery.conf中應(yīng)該配置 primary_slot_name:

standby_mode = 'on'

primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'

primary_slot_name = 'node_a_slot'

級(jí)聯(lián)復(fù)制

級(jí)聯(lián)復(fù)制特性允許一臺(tái)后備服務(wù)器接收復(fù)制連接并且把 WAL 記錄流式傳送給其他后備服務(wù)器, 就像一個(gè)轉(zhuǎn)發(fā)器一樣。可以被用來(lái)減小對(duì)于主控機(jī)的直接連接數(shù)并且使得站點(diǎn)間的帶寬開(kāi)銷(xiāo)最小化。

一臺(tái)同時(shí)扮演著接收者和發(fā)送者角色的后備服務(wù)器被稱(chēng)為一臺(tái)級(jí)聯(lián)后備服務(wù)器。 “更直接”(通過(guò)更少的級(jí)聯(lián)后備服務(wù)器)連接到主控機(jī)的后備服務(wù)器被稱(chēng)為上游服務(wù)器, 而那些離得更遠(yuǎn)的后備服務(wù)器被稱(chēng)為下游服務(wù)器。 級(jí)聯(lián)復(fù)制并沒(méi)有對(duì)下游服務(wù)器的數(shù)量或分布設(shè)定限制, 盡管每個(gè)后備服務(wù)器僅連接到一臺(tái)最終連接到單個(gè)主/備服務(wù)器的上游服務(wù)器。

一臺(tái)級(jí)聯(lián)后備服務(wù)器不僅僅發(fā)送從主控機(jī)接收到的 WAL 記錄, 還要發(fā)送那些從歸檔中恢復(fù)的記錄。因此某些上游連接中的復(fù)制連接被中斷, 只要還有新的 WAL 記錄可用,下游的流復(fù)制都會(huì)繼續(xù)下去。

級(jí)聯(lián)復(fù)制目前是異步的。同步復(fù)制設(shè)置當(dāng)前對(duì)級(jí)聯(lián)復(fù)制無(wú)影響。

不管在什么樣的級(jí)聯(lián)布置中,熱備反饋都會(huì)向上游傳播。

如果一臺(tái)上游后備服務(wù)器被提升為新的主控機(jī),且下游服務(wù)器的 recovery_target_timeline被設(shè)置成'latest', 下游服務(wù)器將繼續(xù)從新的主控機(jī)得到流。

要使用級(jí)聯(lián)復(fù)制,要建立級(jí)聯(lián)后備服務(wù)器讓它能夠接受復(fù)制連接(設(shè)置max_wal_senders和hot_standby, 并且配置基于主機(jī)的認(rèn)證)。 還需要設(shè)置下游后備服務(wù)器中的primary_conninfo指向級(jí)聯(lián)后備服務(wù)器。

同步復(fù)制

PostgreSQL流復(fù)制默認(rèn)是異步的。如果主服務(wù)器崩潰, 則某些已被提交的事務(wù)可能還沒(méi)有被復(fù)制到后備服務(wù)器,這會(huì)導(dǎo)致數(shù)據(jù)丟失。 數(shù)據(jù)的丟失量與故障轉(zhuǎn)移時(shí)的復(fù)制延遲成比例。

同步復(fù)制能夠保證一個(gè)事務(wù)的所有修改都能被傳送到一臺(tái)同步后備服務(wù)器。 這擴(kuò)大了由一次事務(wù)提交所提供的標(biāo)準(zhǔn)持久化級(jí)別。 在計(jì)算機(jī)科學(xué)理論中這種保護(hù)級(jí)別被稱(chēng)為 2-safe 復(fù)制。

在請(qǐng)求同步復(fù)制時(shí),一個(gè)寫(xiě)事務(wù)的每次提交將一直等待, 直到收到一個(gè)確認(rèn)表明該提交在主服務(wù)器和后備服務(wù)器上都已經(jīng)被寫(xiě)入到磁盤(pán)上的預(yù)寫(xiě)日志中。 數(shù)據(jù)會(huì)被丟失的唯一可能性是主服務(wù)器和后備服務(wù)器在同一時(shí)間都崩潰。 這可以提供更高級(jí)別的持久性,盡管只有系統(tǒng)管理員要關(guān)心兩臺(tái)服務(wù)器的放置和管理。 等待確認(rèn)提高了用戶(hù)對(duì)于修改不會(huì)丟失的信心, 但是同時(shí)也不必要地增加了對(duì)請(qǐng)求事務(wù)的響應(yīng)時(shí)間。 最小等待時(shí)間是在主服務(wù)器和后備服務(wù)器之間的來(lái)回時(shí)間。

只讀事務(wù)和事務(wù)回滾不需要等待后備服務(wù)器的回復(fù)。 子事務(wù)提交也不需要等待后備服務(wù)器的響應(yīng),只有頂層提交才需要等待。 長(zhǎng)時(shí)間運(yùn)行的動(dòng)作(如數(shù)據(jù)載入或索引構(gòu)建)不會(huì)等待最后的提交消息。 所有兩階段提交動(dòng)作要求提交等待,包括預(yù)備和提交。

同步備用可以是物理復(fù)制備用或邏輯復(fù)制訂閱者。 它也可以是任何知道如何發(fā)送適當(dāng)反饋消息的物理或邏輯WAL復(fù)制流消費(fèi)者。 除了內(nèi)置的物理和邏輯復(fù)制系統(tǒng)之外,它還包括特殊程序, 如pg_receivewal和pg_recvlogical 以及一些第三方復(fù)制系統(tǒng)和自定義程序。

1) 基本配置

一旦流復(fù)制已經(jīng)被配置,配置同步復(fù)制就只需要一個(gè)額外的配置步驟: synchronous_standby_names必須被設(shè)置為一個(gè)非空值。synchronous_commit也必須被設(shè)置為on,但由于這是默認(rèn)值, 通常不需要改變。這樣的配置將導(dǎo)致每一次提交都等待確認(rèn)消息, 以保證后備服務(wù)器已經(jīng)將提交記錄寫(xiě)入到持久化存儲(chǔ)中。 synchronous_commit可以由個(gè)體用戶(hù)設(shè)置,因此可以在配置文件中配置、 可以為特定用戶(hù)或數(shù)據(jù)庫(kù)配置或者由應(yīng)用動(dòng)態(tài)配置, 這樣可以在一種每事務(wù)基礎(chǔ)上控制持久性保證。

在一個(gè)提交記錄已經(jīng)在主服務(wù)器上被寫(xiě)入到磁盤(pán)后,WAL 記錄接著被發(fā)送到后備服務(wù)器。 每次一批新的 WAL 數(shù)據(jù)被寫(xiě)入到磁盤(pán)后,后備服務(wù)器會(huì)發(fā)送回復(fù)消息, 除非在后備服務(wù)器上wal_receiver_status_interval被設(shè)置為零。 如果根據(jù)主服務(wù)器上synchronous_standby_names的設(shè)置將備用服務(wù)器選為同步備用服務(wù)器, 來(lái)自該后備的回復(fù)消息將被用來(lái)喚醒正在等待提交記錄已被接收確認(rèn)的用戶(hù)。 這些參數(shù)允許管理員指定哪些后備服務(wù)器應(yīng)該是同步后備。 注意同步復(fù)制的配置主要在主控機(jī)上。命名的后備服務(wù)器必須直接連接到主控機(jī), 主控機(jī)對(duì)使用級(jí)聯(lián)復(fù)制的下游后備服務(wù)器一無(wú)所知。

將synchronous_commit設(shè)置為remote_write 將導(dǎo)致每次提交都等待后備服務(wù)器已經(jīng)接收提交記錄并將它寫(xiě)出到其自身所在的操作系統(tǒng)的確認(rèn), 但并非等待數(shù)據(jù)都被刷出到后備服務(wù)器上的磁盤(pán)。這種設(shè)置提供了比on 要弱一點(diǎn)的持久性保障:在一次操作系統(tǒng)崩潰事件中后備服務(wù)器可能丟失數(shù)據(jù), 盡管它不是一次PostgreSQL崩潰。不過(guò),在實(shí)際中它是一種有用的設(shè)置, 因?yàn)樗梢詼p少事務(wù)的響應(yīng)時(shí)間。 只有當(dāng)主服務(wù)器和后備服務(wù)器都崩潰并且主服務(wù)器的數(shù)據(jù)庫(kù)同時(shí)被損壞的情況下, 數(shù)據(jù)丟失才會(huì)發(fā)生。

把synchronous_commit設(shè)置為remote_apply 將導(dǎo)致每一次提交都會(huì)等待,直到當(dāng)前的同步后備服務(wù)器報(bào)告說(shuō)它們已經(jīng)重放了該事務(wù), 這樣就會(huì)使該事務(wù)對(duì)用戶(hù)查詢(xún)可見(jiàn)。在簡(jiǎn)單的情況下, 這允許帶有因果一致性的負(fù)載均衡。

如果請(qǐng)求一次快速關(guān)閉,用戶(hù)將停止等待。不過(guò),在使用異步復(fù)制時(shí), 在所有未解決的 WAL 記錄被傳輸?shù)疆?dāng)前連接的后備服務(wù)器之前,服務(wù)器將不會(huì)完全關(guān)閉。

2)多個(gè)同步后備

同步復(fù)制支持一個(gè)或者更多個(gè)同步后備服務(wù)器,事務(wù)將會(huì)等待, 直到所有同步后備服務(wù)器都確認(rèn)收到了它們的數(shù)據(jù)為止。 事務(wù)必須等待其回復(fù)的同步后備的數(shù)量由synchronous_standby_names指定。 這個(gè)參數(shù)也指定后備服務(wù)器的名稱(chēng)方法(FIRST和ANY)的列表, 以從列出的選項(xiàng)中選擇同步備用數(shù)據(jù)庫(kù)。

FIRST方法指定了一個(gè)基于優(yōu)先級(jí)的同步復(fù)制,并使事務(wù)提交等待, 直到它們的WAL記錄被復(fù)制到根據(jù)其優(yōu)先級(jí)選擇的所請(qǐng)求數(shù)量的同步備用數(shù)據(jù)庫(kù)。 其名稱(chēng)出現(xiàn)在清單前面的備用數(shù)據(jù)庫(kù)被賦予更高的優(yōu)先級(jí),并將被視為同步。 此列表中后面出現(xiàn)的其他備用服務(wù)器代表潛在的同步備用服務(wù)器。 如果任何當(dāng)前的同步備用服務(wù)器因任何原因斷開(kāi)連接, 它將被立即替換為次最高優(yōu)先級(jí)的備用服務(wù)器。

基于優(yōu)先級(jí)的多個(gè)同步后備的synchronous_standby_names示例為:

synchronous_standby_names = 'FIRST 2 (s1, s2, s3)'

在這個(gè)例子中,如果有四個(gè)后備服務(wù)器s1、s2、 s3和s4在運(yùn)行,兩個(gè)后備服務(wù)器s1 和s2將被選中為同步后備,因?yàn)樗鼈兂霈F(xiàn)在后備服務(wù)器名稱(chēng)列表的前部。 s3是一個(gè)潛在的同步后備,當(dāng)s1或s2 中的任何一個(gè)失效,它就會(huì)取而代之。s4 則是一個(gè)異步后備因?yàn)樗拿植辉诹斜碇小?br>

方法ANY指定基于定額的同步復(fù)制,并使事務(wù)提交等待, 直到它們的WAL記錄至少被復(fù)制到列表中的所請(qǐng)求數(shù)量的同步備用數(shù)據(jù)庫(kù)。

基于定額的多個(gè)同步備用數(shù)據(jù)庫(kù)的synchronous_standby_names的一個(gè)例子:

synchronous_standby_names = 'ANY 2 (s1, s2, s3)'

在這個(gè)例子中,如果有四個(gè)備用服務(wù)器s1、s2、 s3和s4正在運(yùn)行,事務(wù)提交將等待來(lái)自s1、 s2和s3中的任意兩個(gè)備用服務(wù)器的回復(fù)。 s4是一個(gè)異步的備用服務(wù)器,因?yàn)樗辉诹斜碇?。

備用服務(wù)器的同步狀態(tài)可以使用pg_stat_replication視圖查看。

)3. 性能規(guī)劃

同步復(fù)制通常要求仔細(xì)地規(guī)劃和放置后備服務(wù)器來(lái)保證應(yīng)用能令人滿(mǎn)意地工作。 等待并不利用系統(tǒng)資源,但是事務(wù)鎖會(huì)持續(xù)保持直到傳輸被確認(rèn)。其結(jié)果是, 不小心使用同步復(fù)制將由于響應(yīng)時(shí)間增加以及較高的爭(zhēng)用率而降低數(shù)據(jù)庫(kù)應(yīng)用的性能。

PostgreSQL允許應(yīng)用開(kāi)發(fā)者通過(guò)復(fù)制來(lái)指定所要求的持久性級(jí)別。 這可以為整個(gè)系統(tǒng)指定,不過(guò)它也能夠?yàn)樘囟ǖ挠脩?hù)或連接指定, 甚至還可以為單個(gè)事務(wù)指定。

例如,一個(gè)應(yīng)用的載荷的組成可能是這樣:10% 的改變是重要的客戶(hù)詳情, 而 90% 的改變是不太重要的數(shù)據(jù),即使它們丟失業(yè)務(wù)也比較容易容忍 (例如用戶(hù)間的聊天消息)。

通過(guò)在應(yīng)用級(jí)別(在主服務(wù)器上)指定的同步復(fù)制選項(xiàng), 我們可以為大部分重要的改變提供同步復(fù)制,并且不會(huì)拖慢整體的載荷。 應(yīng)用級(jí)別選項(xiàng)是使高性能應(yīng)用享受同步復(fù)制的一種重要和實(shí)用的工具。

你應(yīng)該認(rèn)為網(wǎng)絡(luò)帶寬必須比 WAL 數(shù)據(jù)的產(chǎn)生率高。

高可用性規(guī)劃

當(dāng)synchronous_commit被設(shè)置為on或remote_write時(shí), 發(fā)生的提交將等待直至同步后備服務(wù)器回應(yīng)。如果上一個(gè)或者唯一一個(gè)后備服務(wù)器崩潰, 響應(yīng)可能不會(huì)發(fā)生。

防止數(shù)據(jù)丟失的最好解決方案是確保你不會(huì)丟失你的上一個(gè)保持同步的后備服務(wù)器。 這可以通過(guò)使用synchronous_standby_names 命名多個(gè)潛在的同步后備服務(wù)器來(lái)實(shí)現(xiàn)。

在基于優(yōu)先級(jí)的同步復(fù)制中,名稱(chēng)出現(xiàn)在列表中較早的備用服務(wù)器將用作同步備用服務(wù)器。 如果其中一個(gè)現(xiàn)有的備用服務(wù)器失敗,在這些之后列出的備用服務(wù)器將接管同步備用服務(wù)器的角色。

在基于定額的同步復(fù)制中,出現(xiàn)在列表中的所有備用服務(wù)器將用作同步備用服務(wù)器的候選項(xiàng)。 即使其中一個(gè)失敗,其他備用服務(wù)器仍將繼續(xù)扮演同步備用服務(wù)器候選人的角色。

當(dāng)一臺(tái)后備服務(wù)器第一次附加到主服務(wù)器時(shí),它將處于一種還沒(méi)有正確同步的狀態(tài)。 這被描述為追趕模式。一旦后備服務(wù)器和主服務(wù)器之間的遲滯第一次變成零, 我們就來(lái)到了實(shí)時(shí)的流式狀態(tài)。 在后備服務(wù)器被創(chuàng)建之后的很長(zhǎng)一段時(shí)間內(nèi)可能都是追趕模式。如果后備服務(wù)器被關(guān)閉, 則追趕周期將被增加,增加量由后備服務(wù)器被關(guān)閉的時(shí)間長(zhǎng)度決定。 只有當(dāng)后備服務(wù)器到達(dá)流式狀態(tài)后,它才能成為一臺(tái)同步后備。 這個(gè)狀態(tài)可以使用pg_stat_replication視圖查看。

如果在提交正在等待確認(rèn)時(shí)主服務(wù)器重啟, 那些正在等待的事務(wù)將在主數(shù)據(jù)庫(kù)恢復(fù)時(shí)被標(biāo)記為完全提交。 沒(méi)有辦法確認(rèn)所有后備服務(wù)器已經(jīng)收到了在主服務(wù)器崩潰時(shí)所有還未處理的 WAL 數(shù)據(jù)。 某些事務(wù)可能不會(huì)在后備服務(wù)器上顯示為已提交,即使它們?cè)谥鞣?wù)器上顯示為已提交。 我們提供的保證是:在 WAL 數(shù)據(jù)已經(jīng)被后備服務(wù)器安全地收到之前, 應(yīng)用將不會(huì)收到一個(gè)事務(wù)成功提交的顯式確認(rèn)。

如果你真的丟失了你的上一個(gè)后備服務(wù)器,那么你應(yīng)該禁用 synchronous_standby_names并且在主服務(wù)器上重載配置文件。

如果主服務(wù)器與剩下的后備服務(wù)器是隔離的, 你應(yīng)當(dāng)故障轉(zhuǎn)移到那些其他剩余后備服務(wù)器中的最佳候選者上。

如果在事務(wù)等待時(shí)你需要重建一臺(tái)后備服務(wù)器,確保命令 pg_start_backup() 和 pg_stop_backup() 被運(yùn)行在一個(gè)synchronous_commit = off 的會(huì)話(huà)中,否則那些請(qǐng)求將永遠(yuǎn)等待后備服務(wù)器出現(xiàn)。

后備服務(wù)器中的持續(xù)歸檔

當(dāng)在備用數(shù)據(jù)庫(kù)中使用連續(xù)WAL歸檔時(shí),有兩種不同的情況: WAL歸檔可以在主數(shù)據(jù)庫(kù)和備用數(shù)據(jù)庫(kù)之間共享,或者備用數(shù)據(jù)庫(kù)可以有自己的WAL歸檔。 當(dāng)備用數(shù)據(jù)庫(kù)具有自己的WAL歸檔時(shí),將archive_mode設(shè)置為 always,并且備用數(shù)據(jù)庫(kù)將為每個(gè)收到的WAL段調(diào)用歸檔命令, 無(wú)論是從歸檔恢復(fù)或通過(guò)流復(fù)制??梢灶?lèi)似地處理共享歸檔,但是 archive_command必須測(cè)試正在歸檔的文件是否已存在, 以及現(xiàn)有文件是否具有相同的內(nèi)容。這需要在archive_command 中更加小心,因?yàn)樗仨毿⌒牟灰采w具有不同內(nèi)容的現(xiàn)有文件, 但如果完全相同的文件存檔兩次,則返回成功。 如果兩個(gè)服務(wù)器試圖同時(shí)歸檔同一個(gè)文件,則所有必須無(wú)競(jìng)爭(zhēng)的完成。

如果archive_mode設(shè)置為on, 則在恢復(fù)或者待機(jī)模式期間不會(huì)啟用歸檔程序。如果備用服務(wù)器已升級(jí), 它將在升級(jí)后開(kāi)始?xì)w檔,但不會(huì)歸檔其未生成的任何WAL。 要在歸檔中獲取完整的WAL文件系列,必須確保所有WAL在到達(dá)備用數(shù)據(jù)庫(kù)之前都已存檔。 這對(duì)于基于文件的日志傳送是固有的,因?yàn)閭溆脭?shù)據(jù)庫(kù)只能恢復(fù)在歸檔中找到的文件, 但是如果啟用了流復(fù)制,則不會(huì)。當(dāng)服務(wù)器不處于恢復(fù)模式時(shí), on和always模式之間沒(méi)有區(qū)別

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • PostgreSQL備份和恢復(fù) 原創(chuàng)沒(méi)刮胡子 最后發(fā)布于2019-07-18 14:05:10 閱讀數(shù) 190 收...
    不玩了啊閱讀 1,988評(píng)論 0 0
  • pg集群一般由以下8個(gè)場(chǎng)景: 1) 2個(gè)pg服務(wù)器共享一塊數(shù)據(jù)盤(pán):只有主服務(wù)器掛載,主備倒換時(shí)當(dāng)前主服務(wù)器降為備服...
    robot_test_boy閱讀 2,376評(píng)論 0 1
  • | | 備份速度|備份范圍|恢復(fù)范圍|操作影響|備份原理|恢復(fù)成本|| ------- |:---...
    頂兒響叮當(dāng)閱讀 3,626評(píng)論 0 4
  • 久違的晴天,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開(kāi)好到教室時(shí),離放學(xué)已經(jīng)沒(méi)多少時(shí)間了。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,822評(píng)論 16 22
  • 創(chuàng)業(yè)是很多人的夢(mèng)想,多少人為了理想和不甘選擇了創(chuàng)業(yè)來(lái)實(shí)現(xiàn)自我價(jià)值,我就是其中一個(gè)。 創(chuàng)業(yè)后,我由女人變成了超人,什...
    亦寶寶閱讀 2,008評(píng)論 4 1

友情鏈接更多精彩內(nèi)容