由test_decoding學習如何編寫PostgreSQL邏輯解碼外掛
PostgreSQL提供很多介面,允許使用者定製自己需要的功能,很多時候文件並不能讓我們完全理解和把握它們的使用。如果需要開發一個自己的功能,該如何下手?下邊是我作為一名程式碼搬運工的工作方式,供參考。
1、以邏輯複製外掛為例,先看一下它是怎麼執行的:
建立邏輯槽,預設使用test_decoding外掛:
pg_recvlogical --create-slot -S test_slot -d flying
可以根據需要指定其他解碼外掛,引數-P, --plugin=PLUGIN,更多資訊 pg_recvlogical --help
檢視一下
flying=# select * from pg_replication_slots; slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn -----------+---------------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+--------------------- test_slot | test_decoding | logical | 12635 | flying | f | f | | | 926 | 0/F05CA448 | 0/F05CA480
開始邏輯複製,這裡直接列印到標準輸出
pg_recvlogical --start -S test_slot -d flying -f -
給表a(col1 int)插入一條資料:insert into a values(100); 接收端開始輸出:
quanzl-mac:bin quanzl$ ./pg_recvlogical --start -S test_slot -d flying -f -
BEGIN 926
table public.a: INSERT: col1[integer]:100
COMMIT 926
這個外掛更多是演示功能,有人解析它的結果用在生產環境,也是沒問題的。新版本還有一個可以參考的外掛pgoutput,原始碼在src/backend/replication/pgoutput。
更多資料,邏輯複製API文件:
https://www.postgresql.org/docs/11/logicaldecoding-output-plugin.html
2、閱讀理解程式碼,我們可以知道各部分怎樣實現
(1)、初始化時設定回撥函式 _PG_output_plugin_init
結合文件,理解結構體OutputPluginCallbacks各成員分別代表什麼,即使沒有註釋也很容易理解。
(2)、複製啟動引數
pg_recvlogical允許通過 -o 傳遞引數給外掛,從startup_cb可以學習到如何定義我們自己需要的選項。
(3)、各動作解碼,四種:begin、change、truncate、commit
尤其change動作,如何區分 INSERT/UPDATE/DELETE,包括如何正確引用物件名,識別空和TOAST,識別已刪除欄位等等。
(4)、還有一些test_decoding沒用到的功能,比如如何找到複製鍵,預設為主鍵,也可以通過SQL命令設定:ALTER TABLE ... REPLICA IDENTITY ...
這種怎麼辦呢?開啟與此有關的標頭檔案,include/replication 下,根據註釋和名字可以發現它就是 RelationGetReplicaIndex函式。諸如此類 ……
3、自己動手、豐衣足食
理解它是怎麼運作的,接下來就可以做自己想做的事情了。比如給複製接收端傳送標準SQL語句,以便可以複製到其他關係庫;比如允許自定義日期格式,以便能夠讓接收端直接識別(真的有系統使用詭異格式,咱不點名,點名不好)。
經常有人說看不懂程式碼,這說明需要補C語言及其他基礎知識,去買書吧。
歡迎關注我的公眾