if (init_server_components()) unireg_abort(MYSQLD_ABORT_EXIT); 其中init_server_components()會初始化很多模塊Gtid只是其中很小的一個,Innodb就在這里初始化。
gtid_server_init()函數片段如下:
(!(global_sid_lock= new Checkable_rwlock( #ifdef HAVE_PSI_INTERFACE key_rwlock_global_sid_lock #endif )) || !(gtid_mode_lock= new Checkable_rwlock( #ifdef HAVE_PSI_INTERFACE key_rwlock_gtid_mode_lock #endif )) || !(global_sid_map= new Sid_map(global_sid_lock)) || //new一個內存Sid_map內存空間出來 !(gtid_state= new Gtid_state(global_sid_lock, global_sid_map))||//new一個內存Gtid_state內存空間出來 !(gtid_table_persistor= new Gtid_table_persistor()));//new一個內存Gtid_table_persistor內存空間出來 二、初始化獲得本數據庫的server_uuid 這個初始化過程在前文提到了,無非就是通過my.cnf獲得server_uuid,如果沒有則重新生成,具體可以參考一下前文這里不再過多描述。
if (init_server_auto_options()) { sql_print_error("Initialization of the server's UUID failed because it could" " not be read from the auto.cnf file. If this is a new" " server, the initialization failed because it was not" " possible to generate a new UUID."); unireg_abort(MYSQLD_ABORT_EXIT); } 三、初始化Gtid_state全局結構 global_sid_lock->rdlock(); int gtid_ret= gtid_state->init();//將server_uuid對應的sid(Uuid)和sidno加入到 Sid_map中。 global_sid_lock->unlock();
if (gtid_ret) unireg_abort(MYSQLD_ABORT_EXIT); 其實本步驟也是完成了sidno的加入Sid_map中,有興趣的可以參考int Gtid_state::init()函數邏輯非常簡單。
// Initialize executed_gtids from mysql.gtid_executed table. if (gtid_state->read_gtid_executed_from_table() == -1) unireg_abort(1); Gtid_state::read_gtid_executed_from_table只是一層簡單的封裝如下:
int Gtid_state::read_gtid_executed_from_table() { return gtid_table_persistor->fetch_gtids(&executed_gtids); } 接下來看看Gtid_table_persistor::fetch_gtids(Gtid_set *gtid_set)函數邏輯片段
if ((err= table->file->ha_rnd_init(true))) { ret= -1; goto end; }
while(!(err= table->file->ha_rnd_next(table->record[0]))) //開始一行一行讀取數據 { /* Store the gtid into the gtid_set */
/** @todo: - take only global_sid_lock->rdlock(), and take gtid_state->sid_lock for each iteration. - Add wrapper around Gtid_set::add_gno_interval and call that instead. */ global_sid_lock->wrlock(); if (gtid_set->add_gtid_text(encode_gtid_text(table).c_str()) != //此處將讀取到的一行Gtid區間加入到Gtid_state.executed_gtids中。 RETURN_STATUS_OK) { global_sid_lock->unlock(); break; } global_sid_lock->unlock(); } 完成本步驟過后Gtid_state.executed_gtids將設置,主庫和從庫的設置不同