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将设置,主库和从库的设置不同