MySQL外掛呼叫
簡單記錄以備學習,如果有誤請指出。
一、核心類
-
Observer_info:觀察者 rpl_handler.h
class Observer_info { //外掛觀察者public: void *observer; //這個void指標是具體的觀察者,使用指標函式實現多型 st_plugin_int *plugin_int; plugin_ref plugin Observer_info(void *ob, st_plugin_int *p); };
-
實際觀察者
及void* 指向的物件,其中全部都是函式指標,這裡透過函式指標指向了具體的函式,實現了外掛的功能。其中的函式指標指向的實際函式就是需要使用者自己實現的。
Trans_observer 結構體 Server_state_observer 結構體 Binlog_transmit_observer 結構體 Binlog_relay_IO_observer 結構體
實際上看具體實現的時候,搜尋這些結構的名字,外掛中如果實現會定義實際的函式名。如MGR中如下:
Trans_observer trans_observer = { sizeof(Trans_observer), group_replication_trans_before_dml, group_replication_trans_before_commit, group_replication_trans_before_rollback, group_replication_trans_after_commit, group_replication_trans_after_rollback, };
-
Delegate:委託者基類
其中包含
Observer_info_list observer_info_list; //觀察者連結串列,也就是Observer_info的一個連結串列 mysql_rwlock_t lock;//讀寫鎖 MEM_ROOT memroot;//記憶體空間 bool inited;//是否初始化
並且實現了一些通用的函式,比如增加和刪除外掛
-
具體的委託者繼承自Delegate
Trans_delegate :事物相關 typedef Trans_observer Observer; Server_state_delegate :伺服器相關 typedef Server_state_observer Observer; Binlog_transmit_delegate :傳輸相關 typedef Binlog_transmit_observer Observer; Binlog_relay_IO_delegate :slave 相關typedef Binlog_relay_IO_observer Observer;
二、註冊函式
舉例rpl_handler.cc中
int register_trans_observer(Trans_observer *observer, void *p){ return transaction_delegate->add_observer(observer, (st_plugin_int *)p); }
observer已經初始化完成,註冊即可。這裡加入到了觀察者佇列。一旦加入這個連結串列則,在實際使用的時候就會遍歷整個連結串列執行相應的函式。
三、重要的宏
-
RUN_HOOK 宏
定義如下:
#define RUN_HOOK(group, hook, args) \ (group ##_delegate->is_empty() ? \ 0 : group ##_delegate->hook args)#define NO_HOOK(group) (group ##_delegate->is_empty())
這個宏會在MySQL中程式碼的相應合適的位置進行呼叫,進入外掛定義的邏輯。
-
FOREACH_OBSERVER 宏
定義如下:
#define FOREACH_OBSERVER(r, f, thd, args) \ /* Use a struct to make sure that they are allocated adjacent, check delete_dynamic(). */ \ Prealloced_array<plugin_ref, 8> plugins(PSI_NOT_INSTRUMENTED); \ //定義一個外掛陣列 read_lock(); \ Observer_info_iterator iter= observer_info_iter(); \ //迭代器 Observer_info *info= iter++; \ // for (; info; info= iter++) \ { \ plugin_ref plugin= \ my_plugin_lock(0, &info->plugin); \ if (!plugin) \ { \ /* plugin is not intialized or deleted, this is not an error */ \ r= 0; \ break; \ } \ plugins.push_back(plugin); \ if (((Observer *)info->observer)->f \ && ((Observer *)info->observer)->f args) \ { \ r= 1; \ sql_print_error("Run function '" #f "' in plugin '%s' failed", \ info->plugin_int->name.str); \ break; \ } \ } \
實際上可以看到是在遍歷相應的實際委託者的連結串列observer_info_list,執行相應的回表函式。
四、一個實際的列子
RUN_HOOK(transaction, before_commit, (thd, all, thd_get_cache_mngr(thd)->get_binlog_cache_log(true), thd_get_cache_mngr(thd)->get_binlog_cache_log(false), max<my_off_t>(max_binlog_cache_size, max_binlog_stmt_cache_size))
根據RUN_HOOK定義 group ##_delegate->hook args 轉換為:
transaction_delegate->before_commit(thd, all, thd_get_cache_mngr(thd)->get_binlog_cache_log(true), thd_get_cache_mngr(thd)->get_binlog_cache_log(false), max<my_off_t>(max_binlog_cache_size, max_binlog_stmt_cache_size)
此處的transaction_delegate是一個已經初始化的並且已經有外掛註冊的Trans_delegate類的全域性物件。因為Trans_delegate繼承來自Delegate,而在Trans_delegate中實現了before_commit的邏輯。其中包含的宏呼叫
FOREACH_OBSERVER(ret, before_commit, thd, (¶m)); //這裡會執行回撥函式宏定義:(#define FOREACH_OBSERVER(r, f, thd, args) )
做回撥,實際上他會遍歷整個transaction_delegate中的觀察者,這些觀察者就是每一個外掛實現的特定的GROUP的功能,所以FOREACH_OBSERVER宏的這一句
((Observer *)info->observer)->f args
就裝換為了(Trans_observer *)info->observer)->before_commit(¶m) 其中info是一個Observer_info物件其中包含了一個VOID指標observer,可以轉換為需要的型別,而Trans_observer是一個結構體其中全部都是函式指標before_commit是一個函式指標指向了group_replication_trans_before_commit,整個回撥過程完成。
五、一張呼叫圖
呼叫圖如下:
RUN_HOOK.png
作者微信:
微信.jpg
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2199948/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 外掛如何呼叫本外掛的View?View
- EOSIO MySQL 外掛 issue 2MySql
- EOSIO MySQL 外掛 issue 1MySql
- C# 免註冊呼叫大漠外掛C#
- 外掛的裡控制器可以怎麼呼叫外掛裡的配置資訊
- MySQL審計外掛介紹MySql
- MySQL 密碼增強外掛MySql密碼
- Android外掛化技術之旅 1 開篇 - 實現啟動外掛與呼叫外掛中的Activity和ServiceAndroid
- Qt自定義外掛plugin的開發和呼叫QTPlugin
- MySQL連線控制外掛介紹MySql
- mysql使用mariadb審計外掛MySql
- MySQL 5.7.24安裝MySQL審計外掛小記MySql
- 外掛化之程式碼呼叫與載入資源
- [20170725]vim呼叫bccalc外掛問題.txt
- apisix~14在自定義外掛中呼叫proxy_rewriteAPI
- MySQL審計外掛-MariaDB Audit PluginMySqlPlugin
- Netdata Mysql執行情況監控外掛MySql
- [外掛擴充套件]書架外掛(新外掛後臺)套件
- 外掛 檔案上傳外掛 ajaxfileupload.js外掛JS
- 外掛
- Flutter學習(9)——Flutter外掛實現(Flutter呼叫Android原生FlutterAndroid
- Qt學習--Qt Plugin建立及呼叫2(外掛管理器)QTPlugin
- [外掛擴充套件]更新IP外掛套件
- [外掛擴充套件]廣告外掛2.0套件
- [外掛擴充套件]附件Attachment外掛套件
- [外掛擴充套件]Ping外掛套件
- [外掛擴充套件]投票外掛1.0套件
- [外掛擴充套件]騰訊分析外掛套件
- [外掛擴充套件]外掛需求徵集套件
- mybatis generator外掛系列--分頁外掛MyBatis
- SVN外掛和Tomcat外掛地址Tomcat
- MySQL5.6 audit審計外掛安裝初探MySql
- MySQL不再支援Berkeley DB 轉而新增外掛(轉)MySql
- vim外掛的安裝方式 -- vim註釋外掛和doxygen函式註釋生成外掛-ctrlp外掛-tabular等號對齊 外掛...函式
- rabbitMQ 延遲佇列外掛強制呼叫ReturnCallback裡returnedMessage方法MQ佇列
- Rainbond外掛擴充套件:基於Mysql-Exporter監控MysqlAI套件MySqlExport
- [外掛擴充套件]焦點圖外掛套件
- [外掛擴充套件]友情連結——外掛套件