程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL中innodb引擎分析(初始化)

MySQL中innodb引擎分析(初始化)

編輯:MySQL綜合教程

MySQL中innodb引擎分析(初始化)


MySQL的存儲引擎是以插件形式工作的,這應該是MySQL的一大特色了吧!根據《深入理解MySQL》的內容,5.1版本時存儲引擎的插件化都還不是徹底,確切的說是剛添加的特性。為MySQL添加一個存儲引擎時,需要更改一些上層代碼,零散的更改本來就有點麻煩,同時工程也要重新編譯一次。我聽別人說,已經可以不改C/C++代碼就直接添加引擎了。這樣的話,折騰存儲引擎的話就更方便了! 這段代碼來自ha_innodb.cc,這是MySQL中申明存儲引擎插件的標准過程。這段代碼利用了宏。在plugin.h中有比較完整的定義。
mysql_declare_plugin(innobase)
{
  MYSQL_STORAGE_ENGINE_PLUGIN,
  &innobase_storage_engine,
  innobase_hton_name,
  plugin_author,
  "Supports transactions, row-level locking, and foreign keys",
  PLUGIN_LICENSE_GPL,
  innobase_init, /* Plugin Init */
  NULL, /* Plugin Deinit */
  INNODB_VERSION_SHORT,
  innodb_status_variables_export,/* status variables             */
  innobase_system_variables, /* system variables */
  NULL, /* reserved */
  0,    /* flags */
},
i_s_innodb_trx,
i_s_innodb_locks,
i_s_innodb_lock_waits,
i_s_innodb_cmp,
i_s_innodb_cmp_reset,
i_s_innodb_cmpmem,
i_s_innodb_cmpmem_reset
mysql_declare_plugin_end;    
我以前看了一本《MySQL技術內幕:innodb存儲引擎》,個人感覺這本書雖然名字像是講底層的,其實還是面向運維的。書中基本上沒有剖析代碼,都是用是文字和例子來講解。我簡略地看了一遍,大概懂了一點東西,但是明顯覺得不夠爽。因為心中很多的疑惑沒法解釋。《深入理解MySQL》裡面的demo存儲引擎倒是有比較詳細的解釋,但是感覺和innodb這樣的“高大上”還是沒法比的。沒辦法了,只能硬著頭皮上代碼了!我是帶著問題來看代碼的,寫的東西肯定不是系統的。 我心中最大的疑惑是,innodb為什麼可以是多線程的?《深入》中的引擎、csv什麼的都根本看不到了多線程的影子。在插件式的架構中,innodb其實就是一個動態庫。這個動態庫內部實現了多線程架構,總覺的不太踏實。如果這動態庫被別的MySQL實例加載了,到底會不會有問題?(當然這個問題感覺我短時間回答不了)。 回到正題,這個innodb的存儲插件聲明中有一個innobase_init字段。- innobase_init是一個函數,它被賦值給誰了呢?看plugin.h中的代碼片段。
struct st_mysql_plugin
{
  int type;             /* the plugin type (a MYSQL_XXX_PLUGIN value)   */
  void *info;           /* pointer to type-specific plugin descriptor   */
  const char *name;     /* plugin name                                  */
  const char *author;   /* plugin author (for I_S.PLUGINS)              */
  const char *descr;    /* general descriptive text (for I_S.PLUGINS)   */
  int license;          /* the plugin license (PLUGIN_LICENSE_XXX)      */
  int (*init)(void *);  /* the function to invoke when plugin is loaded */
  int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
  unsigned int version; /* plugin version (for I_S.PLUGINS)             */
  struct st_mysql_show_var *status_vars;
  struct st_mysql_sys_var **system_vars;
  void * __reserved1;   /* reserved for dependency checking             */
  unsigned long flags;  /* flags for plugin */
};
就是這個init函數指針,當插件別加載的時候,就會調用這innobase_init()函數。innobase_init()函數會調用innobase_start_or_create_for_mysql()函數。我們可以仔細看看這個函數,多線程的玄機都在這個函數中。我把新建線程的代碼摘取了出來。
    for (i = 0; i < srv_n_file_io_threads; i++) {
        n[i] = i;

        os_thread_create(io_handler_thread, n + i, thread_ids + i);
    }
    /*****
    *****/
        /* Create the thread which watches the timeouts for lock waits */
    os_thread_create(&srv_lock_timeout_thread, NULL,
             thread_ids + 2 + SRV_MAX_N_IO_THREADS);

    /* Create the thread which warns of long semaphore waits */
    os_thread_create(&srv_error_monitor_thread, NULL,
             thread_ids + 3 + SRV_MAX_N_IO_THREADS);

    /* Create the thread which prints InnoDB monitor info */
    os_thread_create(&srv_monitor_thread, NULL,
             thread_ids + 4 + SRV_MAX_N_IO_THREADS);
    /*****
    *****/
    os_thread_create(&srv_master_thread, NULL, thread_ids
         + (1 + SRV_MAX_N_IO_THREADS));

除了上面的幾個線程,還有一個可選的purge線程。一般情況下,innodb存儲引擎會有大概八個線程。這個結論和《MySQL技術內幕》的還是很接近的,我們看的innodb版本應該不一樣。這大概就是innodb引擎多線程架構的初始化過程,進一步研究innodb的架構就應該去看各個線程的工作函數,以及它們之間的同步及通信機制了。
至於我那個“動態庫被別的MySQL實例加載的問題”。我覺得在這個情形下,動態庫的機制並不是為了代碼重復利用,而是基於模塊化的軟件設計思想。這裡的引擎不應該被別的MySQL實例加載。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved