2015-11-20 34 views
7

問題:在Hot Standby模式下,您是否可以在從屬設備上應用WAL更新(從屬角色爲報表數據庫服務器)時運行長時間運行的查詢(30s +)嗎? ?現在它的工作方式是,無論是設置下面的參數以殺死長時間運行的查詢,以便可以應用WAL更新,也可以無限期地延遲WAL更新,直到沒有查詢運行來應用它們。我們可以兼得嗎?長時間運行的查詢和WAL更新同時應用?Postgres熱備份和從站上的長時間運行查詢

案例實施:我們目前正在使用熱備模式來同步從一個主機到一個從機的任何更改。從屬角色是一個報告數據庫服務器,查詢不斷並且正在同時運行(有些以毫秒爲單位,有的以秒爲單位,有的在幾分鐘內)。在從屬設備上運行沒有活動查詢的間隔是非常罕見的。

我們調整這兩個參數,以允許長的查詢熱備:

max_standby_archive_delay = -1 # max delay before canceling queries 
max_standby_streaming_delay = -1 # max delay before canceling queries 

而且看着一個Postgres類似我們這樣的歸檔郵件問題郵件列表:

http://www.postgresql.org/message-id/[email protected]

我瞭解在查詢運行時阻止WAL更新應用於 從站的概念。但是,我認爲使用MVCC, 在應用WAL更新的同時,從站(長時間運行,30秒+)上的活動查詢可以從一個版本/快照運行讀取 ,因此 後續查詢將獲得WAL當WAL交易是 時提交更新。我還沒有完全消化PostgreSQL中使用的MVCC模型,但 [https://devcenter.heroku.com/articles/postgresql-concurrency],所以這是 只是我的假設 - 即使在WAL更新期間刪除/截斷表,當前運行的查詢應該仍然工作,因爲它是使用它正在查詢的表的 版本/快照?

摘要:反正是有(即使有第三方擴展),我們可以同步從站從主 ,並有從主這些更新馬上同時任何執行時間讓查詢繼續適用於 奴隸到 一直運行直到它們在待機/從機上完成?如果熱備不能這樣做, 你會爲這種情況推薦什麼?我們的場景是,我們 不斷查詢postgres並且同時運行查詢(有些在 毫秒內,有的在幾秒鐘內,有的在幾分鐘內),幾乎沒有時間讓WAL 更新被應用。我們已經使用Bucardo,但在這種情況下,這不會是一個好的 選擇,因爲我們超過200多個表需要同步 ,包括視圖以及除我們主要的 數據庫之外的其他40個數據庫。

任何幫助將不勝感激。

謝謝!

回答

0

PostgreSQL是一個非常好的數據庫引擎,因爲大多數查詢都不會鎖定表。在內部,它在表格的每一行都有一種修訂系統,這意味着它可以在您的其他閱讀事務中繼續編寫WAL。

日誌也很難延遲,除非你有大量的流量,它總是會在某個時刻趕上。

只要確保你不使用鎖定命令,你會沒事的。

9

感謝Guillaume爲您的答案,但幸運的是,從PostgreSQL 9.1開始,PostgreSQL擁有hot_standby_feedback選項(您在postgresql.conf中設置備用服務器),該選項不會殺死長時間運行的查詢,並且將允許WAL更新備用服務器。對於這個答案的信用可以通過PostgreSQL郵件列表(Raja/Albe/Scott)上的三個人在郵件線程中幫助我完成。希望這可能有助於有人在stackoverflow上搜索這個答案。電子郵件線程可以在這裏找到:

http://www.postgresql.org/message-id/D274E3C1.1113E8%[email protected]

http://www.postgresql.org/docs/9.1/static/hot-standby.html

摘錄:如果發現備用查詢取消的數量是不可接受

補救的可能性存在。第一個選項是設置參數hot_standby_feedback,這可以防止VACUUM刪除最近死的行,因此不會發生清理衝突。如果你這樣做,你應該注意到這將延遲清理主要的死行,這可能會導致不希望的表膨脹。但是,清理情況不會比直接在主服務器上運行備用查詢的情況更糟,並且您仍然可以獲得將備份執行卸載到備用服務器上的好處。在這種情況下,max_standby_archive_delay必須保持較大,因爲延遲WAL文件可能已經包含與所需備用查詢衝突的條目。

解決方案實施

這裏是你的postgresql.conf應該配置到備用服務器上:

max_standby_archive_delay = -1 
max_standby_streaming_delay = -1 
hot_standby_feedback = on 
+0

點上!希望這有助於其他人; **不要忘記重新啓動您的數據庫/服務器! (例如,如果你正在運行RDS)** – Volte