中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

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

汤原县| 新兴县| 保靖县| 游戏| 盐边县| 祁门县| 仁怀市| 兰州市| 秦皇岛市| 高尔夫| 临澧县| 枣强县| 汝城县| 阿荣旗| 东海县| 台中县| 长治市| 三门县| 福建省| 资兴市| 汤阴县| 巫山县| 彝良县| 大关县| 临桂县| 竹山县| 舟山市| 龙游县| 岳普湖县| 格尔木市| 西昌市| 临颍县| 牙克石市| 雷山县| 登封市| 黄大仙区| 南丹县| 高清| 福建省| 同心县| 漳浦县|