從源碼角度看MySQL memcached plugin——1. 系統結構和引擎初始化

来源:http://www.cnblogs.com/ohmhong/archive/2017/05/21/6886150.html
-Advertisement-
Play Games

本章嘗試回答兩個問題: 一、memcached plugin與MySQL的關係; 二、MySQL系統如何啟動memcached plugin。 1. memcached plugin與MySQL的關係 該圖是從MySQL官方文檔里對memcached的介紹圖片。從圖中可以看出,memcached的結 ...


本章嘗試回答兩個問題:
一、memcached plugin與MySQL的關係;
二、MySQL系統如何啟動memcached plugin。

1. memcached plugin與MySQL的關係

該圖是從MySQL官方文檔里對memcached的介紹圖片。從圖中可以看出,memcached的結構是由三個部份組成:memcached plugin、innodb_memcached和Innodb API。

在源碼中,memcached plugin部份的代碼會被編譯成libmemcached.so;innodb_memcache和InnoDB API會被編譯成innodb_engine.so。

memcached plugin層通過一組回調函數調用libmemcached.so提供的介面實現為App服務。

InnoDB API層同樣也是通過一組回調函數調用InnoDB層的介面實現,功能類似於圖中左側的Handler API。而innodb_memcache通過包裝這組回調函數為memcached plugin提供介面實現。

2. MySQL系統如何啟動memcached plugin

在MySQL中,InnoDB存儲引擎和memcached都是以插件的形式實現。memcached最底層的回調函數是由InnoDB存儲引擎提供,於是在插件初始化的順序上是InnoDB插件先於memcached插件。

InnoDB存儲引擎插件調用plugin_initialize函數初始化時將一組回調函數數組的地址傳給全局指針變數innodb_callback_data。memcached引擎插件調用plugin_initialize函數初始化時將innodb_callback_data作為自己的參數傳入。

插件初始化使用的函數plugin_initialize的函數原型是int plugin_initialize(st_plugin_int *plugin);
參數類型為st_plugin_int的結構體。MySQL使用該結構體描述一個插件。其中有兩個變數,data和plugin。plugin變數存放了插件的init和deinit回調函數,這是插件初始化時真實調用的函數;data作為plugin中的回調函數的參數存在。

int plugin_initialize(st_plugin_int *plugin);

/* A handle of a plugin */
struct st_plugin_int
{
  ...
  st_mysql_plugin *plugin;
  void *data;                   /* plugin type specific, e.g. handlerton */
  ...
};

struct st_mysql_plugin
{
  ...
  int (*init)(MYSQL_PLUGIN);  /* the function to invoke when plugin is loaded */
  int (*deinit)(MYSQL_PLUGIN);/* the function to invoke when plugin is unloaded */
  ...
};

3.1 InnoDB如何將回調函數傳給全局變數innodb_callback_data

InnoDB層提供的回調函數是個數組,數組名為innodb_api_cb。

ib_cb_t innodb_api_cb[] = {
    (ib_cb_t) ib_cursor_open_table,
    ...
};

在plugin_initialize函數里,調用plugin->plugin->init函數(innobase_init函數)。如上圖:

  1. 將innodb_api_cb數組的地址賦值到在plugin->data->data中。
  2. 將plugin->data->data賦值到innodb_callback_data。

到此可以看到innodb_callback_data已經指向了一個回調函數數組的地址。

3.2 memcached如何將innodb_callback_data賦值給innodb_engine.so中的回調函數

初始化memcached插件同樣調用的是plugin_initialize函數,將innodb_callback_data賦值給plugin->data之後,調用plugin->plugin->init函數(daemon_memcached_plugin_init函數)。

完成了插件初始化的基本操作之後,開啟一個新的線程daemon_memcached_main,這個線程是memcached插件系統的daemon線程。

void daemon_memcached_main(memcached_context_t* p);

struct memcached_context
{
    char*       m_engine_library;
    char*       m_mem_option;
    void*       m_innodb_api_cb;
    unsigned int    m_r_batch_size;
    unsigned int    m_w_batch_size;
    bool        m_enable_binlog;
};

在開啟線程daemon_memcached_main之前,會將plugin->data(innodb_callback_data)賦值給p->m_innodb_api_cb。

daemon_memcached_main在進入守護狀態之前,還有兩個重要的操作要做,分別是load engine和init engine函數。而這兩個函數分別做了什麼?

  1. load engine: 連接libmemcached.so的回調函數與innodb_engine.so的實現。
  2. init engine: 連接innodb_engine.so的innodb_callback_API的回調函數與InnoDB層的實現。

3.2.1 load engine

load_engine(engine, get_server_api,settings.extensions.logger,
 &engine_handle);

load_engine的函數原型如上。在這個過程中,會load兩個引擎。一個innodb_engine,一個是default_engine。
過程如下:

  1. 調用dlopen打開innodb_engine.so。
  2. 調用dlsym函數獲得create_instance函數的地址。
  3. 調用create_instance,malloc一個struct innodb_engine的結構體innodb_engine,為innodb_engine回調函數賦值。
  4. 調用create_instance|create_my_default_instance為預設引擎的回調函數賦值。

load engine之後,lib_memcached.so中的回調函數會被賦值,實現是在innodb_engine.so中。

InnoDB Engine與Default Engine是否啟用?是否同時啟用?

/** Cache options, tells if we will used Memcached default engine or InnoDB
Memcached engine to handle the request */
typedef enum meta_cache_opt {
    META_CACHE_OPT_INNODB = 1,  /*!< Use InnoDB Memcached Engine only */
    META_CACHE_OPT_DEFAULT,     /*!< Use Default Memcached Engine only */
    META_CACHE_OPT_MIX,     /*!< Use both, first use default memcached engine */
    META_CACHE_OPT_DISABLE,     /*!< This operation is disabled */
    META_CACHE_NUM_OPT      /*!< Number of options */
} meta_cache_opt_t;

預設的參數值為META_CACHE_OPT_INNODB,僅僅啟用InnoDB Engine,數據通過InnoDB引擎提供的Callback方法操作;若同時啟用了Memcached Default Engine(META_CACHE_OPT_MIX),那麼數據讀取時,首先從Default Engine中讀取;記錄刪除時,也需要先刪除Default Engine中的記錄。

3.3.2 init engine

init engine調用的函數是

innodb_eng->engine.v1->initialize

實際上調用的是實現在在innodb_engine.so的innodb_initialize函數。

在這個innodb_initialize函數中調用register_innodb_cb函數為innodb_memcached_api數組賦值。兩個數組的指針順序要一一對應。

innnodb_memcached_api數組是innodb_engine.so中調用innodb層操作的回調函數數組。

以下這圖是這個過程中innodb的函數指針一路傳遞到memcached的innodb_engine.so中的函數指針的過程。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在導出資料庫dmp文件時,有資料庫表空記錄的情況下,該空表不會被導出表結構,應用如下格式代碼: select 'alter table ' || table_name || ' allocate extent(size 64k);' sql_text, table_name, tablespace_ ...
  • " 1、SQL 語句分類 " "1.1、分類方法及類型" "1.2、數據定義語言" "1.3、數據操縱語言" "1.4、其它語句" " 2、動態 SQL 理論 " "2.1、動態 SQL 的用途" "2.2、動態 SQL 的語法" "2.3、綁定變數" " 3、動態 SQL 實戰 " "3.1、封裝 ...
  • 在日常工作中,會碰到如下的場景,如mysql資料庫升級,主伺服器硬體升級等,這個時候就需要將寫操作切換到另外一臺伺服器上,那麼如何進行線上切換呢?同時,要求切換過程短,對業務的影響比較小。 MHA就提供了這樣一種優雅的方式,只會堵塞業務0.5~2s的時間,在這段時間內,業務無法讀取和寫入。 集群信息 ...
  • 這裡向大家介紹一個新的生成T-SQL腳本的SQL Server命令行工具:mssql-scripter。它支持在SQL Server、Azure SQL DB以及Azure SQL DW中為資料庫生成CREATE和INSERT T-SQL腳本。 Mssql-scripter是一個跨平臺的命令行工具, ...
  • 前幾天朋友問我,關於SQLServer資料庫中對樹形結構的表數據統計問題,需求大致如下: 分類表(遞歸數據),A的子分類是B,B的子分類是C……分類關係不間斷,A為第一層,B為第二層,C為第三層……需要統計“每個分類所在的層數”、“子分類的總數”和“子分類的層數”。 ...
  • 此文為慕課網MySql學習筆記,地址:http://www.imooc.com/learn/122 一、在my.ini中配置預設字元集為utf8 a.客戶端:[mysql] default-character-set=utf8 b.服務端:[mysqld] character-set-server= ...
  • MHA(Master High Availability)是一套相對成熟的MySQL高可用方案,能做到在0~30s內自動完成資料庫的故障切換操作,在master伺服器不宕機的情況下,基本能保證數據的一致性。 它由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。其中,MH ...
  • 描述 大家通常禁止在生產環境直接使用select * 已成常識了,也常常在開發規範中就會規定不允許直接使用select *,那麼我們為什麼不允許使用select * ,在一些什麼場景下select * 會出問題?能否控制不能直接使用select *?出於這些疑問,我們特別測試記錄一下。 測試環境 M ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...