August 21, 2012

[MySQL源码] Innodb如何处理auto_inc值

转载请署名:印风 ——————————————————– ha_innobase::write_row是向innodb写入记录的函数,进入函数时自增列的值还没被设置(如何是NULL的话),会调用handler::update_auto_increment来获取并更新自增列,然后再调用row_insert_for_mysql来实际插入记录。我们的精力主要集中在update_auto_increment及其调用的函数上。 先了解下handler的几个跟自增列相关的成员变量(根据注释及gdb推测):  a. ulonglong next_insert_id;   下一个插入自增列的值,当一次插入多行记录时(例如,insert select 操作),第一个没有指定自增列值的记录会从get_auto_increment函数获取的值并赋值给next_insert_id,这样对于剩下的记录就可以直接使用next_insert_id(每次都修改该值)。 b. ulonglong insert_id_for_cur_row;  当前记录的insert id 。第一次成功插入后,这个值被存储到THD::first_successful_insert_id_in_cur_stmt c. Discrete_interval auto_inc_interval_for_cur_row; 从get_auto_increment函数获取的insert id区间。 Discrete_interval 结构体又包含三个值 interval_min  区间的最小值 interval_values 区间内可用自增值的个数 interval_max 最大值 d.  uint auto_inc_intervals_count; 当前插入语句保留的自增区间数 e.  estimation_rows_to_insert 估计将要插入的记录数,在函数handler::ha_start_bulk_insert()中被设置,值为0表示未知。 ////////////////////////////////////////////////////////////////////////////////////////////////////// 下面来分析下handler::update_auto_increment主要流程 1.首先判断自增列是否已经赋值,或者是否不可以为NULL&&sql_mode为MODE_NO_AUTO_VALUE_ON_ZERO时,不做处理 if ((nr= table->next_number_field->val_int()) != 0 ||       (table->auto_increment_field_not_null &&       thd->variables.sql_mode & […]