91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL插件調用

發布時間:2020-08-08 09:33:09 來源:ITPUB博客 閱讀:189 作者:gaopengtttt 欄目: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, (&param)); //這里會執行回調函數宏定義:(#define FOREACH_OBSERVER(r, f, thd, args)  )

做回調,實際上他會遍歷整個transaction_delegate中的觀察者,這些觀察者就是每一個插件實現的特定的GROUP的功能,所以FOREACH_OBSERVER宏的這一句

((Observer *)info->observer)->f args

就裝換為了(Trans_observer *)info->observer)->before_commit(&param) 其中info是一個Observer_info對象其中包含了一個VOID指針observer,可以轉換為需要的類型,而Trans_observer是一個結構體其中全部都是函數指針before_commit是一個函數指針指向了group_replication_trans_before_commit,整個回調過程完成。

五、一張調用圖

調用圖如下:


MySQL插件調用

RUN_HOOK.png

作者微信:


MySQL插件調用

微信.jpg


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丹巴县| 逊克县| 宜城市| 榆中县| 巴青县| 尚义县| 昌乐县| 富平县| 万盛区| 宜城市| 华安县| 青冈县| 琼结县| 和平县| 法库县| 高雄县| 永德县| 西林县| 沁源县| 安溪县| 民权县| 孟津县| 轮台县| 和硕县| 绥滨县| 衢州市| 成武县| 林甸县| 城固县| 久治县| 渭源县| 罗江县| 天全县| 祁阳县| 尼勒克县| 靖江市| 准格尔旗| 乌恰县| 青阳县| 秦安县| 太白县|