PostgreSQL 10.0 preview 功能增強 - 備庫支持邏輯訂閱, 支持訂閱漂移
標簽
PostgreSQL , 10.0 , 主備漂移 , 邏輯複製
背景
邏輯複製的本質是從WAL日誌中,翻譯出邏輯的數據(ROW),然後同步到下遊節點。實際上是一個發布和訂閱的流程。
那麼有兩個問題,
1. 當上遊節點使用了流複製搭建主備HA,並且主備發生切換時,下遊節點的訂閱還能繼續嗎?
2. 可以使用備庫節點作為邏輯複製的上遊節點嗎?(即物理備庫作為邏輯複製的發布節點)
要回答這2個問題,我們要聚焦到WAL日誌的翻譯工作上。換句話說,備庫能不能承擔翻譯WAL的工作。
翻譯WAL要用到什麼呢?
1. WAL日誌,主庫和備庫的WAL日誌是一樣的,所以這個條件是具備的。
2. CATALOG,將WAL翻譯成ROW,必須要知道當時的表結構是啥樣的。由於表結構可能變化,或者表可能被刪除,CATALOG會發生變化,那麼這些dead tuple必須要保留到翻譯對應的WAL還需要它時。在主庫上麵,記錄了邏輯訂閱端的xmin以及catalog xmin,查看pg_replication_slots視圖得到,也就知道哪些CATALOG DEAD TUPLE需要被保留。但是備庫呢?備庫如果要作為邏輯複製的發布者,必須它的訂閱者消費的截至catalog xmin(即需要保留的dead tuple)上報給(上報WAL LSN是沒用的,因為WAL在主庫可能已經清除了)。上報catalog xmin通過什麼方法呢?流複製協議即可。
PS:
PostgreSQL的邏輯複製不像MYSQL,MYSQL需要將所有的WAL都翻譯成BINLOG,實際上目標可能隻訂閱一張表,那麼就不需要浪費這麼多的開銷。
PostgreSQL的發布端隻需要將被訂閱的表產生的WAL翻譯成ROW傳輸給訂閱端,這塊是很節約空間的。但是請注意,這可能也是CATALOG膨脹的原因之一,比如訂閱端一直不訂閱,那麼這個catalog xmin就一直不動,如果接下來主庫發生了大量的表結構變化,或者大量TEMP TABLE的使用(導致了大量的CATALOG垃圾產生),可能導致catalog的膨脹。
好了,進入正題,10.0到底做了什麼來支持備庫可以作為邏輯複製的發布者?
由於主庫保留了所有訂閱者中最小的CATALOG XMIN的catalog dead tuple,所以,即使發生了HA,訂閱者1,依舊可以漂移到下遊節點,繼續訂閱。
換句話說10.0支持邏輯訂閱的漂移了。
10.0流複製協議改進,支持feedback回傳catalog xmin
10.0 流複製協議, feedback消息格式如下,支持了備庫反饋catalog xmin,支持級聯備庫,一路反饋到頂端的主庫。
https://www.postgresql.org/docs/devel/static/protocol-replication.html
Hot Standby feedback message (F)
Byte1('h')
Identifies the message as a Hot Standby feedback message.
Int64
The client's system clock at the time of transmission, as microseconds since midnight on 2000-01-01.
Int32
The standby's current global xmin, excluding the catalog_xmin from any replication slots. If both this value and the following catalog_xmin are 0 this is treated as a notification that Hot Standby feedback will no longer be sent on this connection. Later non-zero messages may reinitiate the feedback mechanism.
Int32
The epoch of the global xmin xid on the standby.
Int32
The lowest catalog_xmin of any replication slots on the standby. Set to 0 if no catalog_xmin exists on the standby or if hot standby feedback is being disabled.
Int32
The epoch of the catalog_xmin xid on the standby.
有了這個協議,備庫就能把它的訂閱者需要的catalog xmin反饋給上遊頂端的主庫。主庫隻要不清理catalog dead tuple,那麼物理備庫就可以愉快的支持邏輯訂閱了。
注意
如果主庫頻繁的使用臨時表,會導致catalog大量的insert, delete(特別是pg_attribute, pg_class,容易膨脹),如果物理備庫的級聯邏輯備庫複製較慢(那麼它需要的catalog xmin會更早),可能引發膨脹。
社區有計劃推出不在catalog內的臨時表,或者持久化臨時表。可以解決這個問題。
https://wiki.postgresql.org/wiki/Postgres_Professional_roadmap
Better temporary tables
Temporary tables outside of system catalog
Some applications create temporary tables at a very high rate. In such cases, writing all of these temporary tables to system catalog becomes an issue, as:
1. System catalog suffers from bloat;
2. OIDs are consumed at high rate with risk of wraparound.
The possible solution of this problem is to store temporary table meta-information in memory without touching persistent data structures.
Temporary tables on standbys
Temporary tables on standbys is a very frequently asked for feature. Assuming we can store temporary table meta-information in-memory, we can implement single-transaction temporary tables on standbys. In order to implement multi-transaction temporary tables we need to solve the MVCC problem. Currently, standby receives information about xids from master and can't issue any xid itself. The solution could be in introduction of parallel axis of "local xids" on standby.
這個patch的討論,詳見郵件組,本文末尾URL。
PostgreSQL社區的作風非常嚴謹,一個patch可能在郵件組中討論幾個月甚至幾年,根據大家的意見反複的修正,patch合並到master已經非常成熟,所以PostgreSQL的穩定性也是遠近聞名的。
參考
https://www.postgresql.org/docs/devel/static/protocol-replication.html
https://blog.2ndquadrant.com/failover-slots-postgresql/
最後更新:2017-04-01 17:00:39