返回首页
当前位置: 主页 > 网络编程 > Php实例教程 >

[MySQL 源码] innodb如何创建二级索引

时间:2012-08-30 15:56来源:知行网www.zhixing123.cn 编辑:麦田守望者

ha_innobase::add_index是innodb创建索引的接口函数。

以下所有的讨论都是基于创建一个非聚集的二级索引。因此一些过程是被省略掉了。
 

1.获取数据词典信息

indexed_table = dict_table_get(prebuilt->table->name, FALSE);

2.检查索引键是否可用

error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table);

3.检查索引列长度

4.

a.创建一个trx对象用于操作innodb数据词典,并创建新的数据词典信息

如果是主键,加LOCK_X,否则加LOCK_S锁
 

b.加数据词典锁row_mysql_lock_data_dictionary(trx);

c.在ibdata的SYS_INDEXES中加载新的数据词典信息

d.trx_commit_for_mysql(trx); 提交刚刚创建的trx

e.row_mysql_unlock_data_dictionary(trx)

以上步骤完成了对ibdata数据词典内的更新,在 完成后释放锁,这时候,如果在后续的row_merge_build_indexes时crash掉。trx_rollback_active不会drop掉新索引。
 

5.

调用函数row_merge_build_indexes实际创建索引,我们的讨论主要集中于此。

row_merge_build_indexes会读取表的聚集索引记录,创建临时表来保存这些记录,并使用合并排序算法进行排序以创建索引

a.

首先初始化merge file相关的数据结构,并初始化
 

merge_files = mem_alloc(n_indexes * sizeof *merge_files);

block_size = 3 * sizeof *block;

block = os_mem_alloc_large(&block_size);

merge_files用于管理针对每个索引创建的临时文件。

block类型为row_merge_block_t,其定义如下:

typedef byte row_merge_block_t[1048576];

因此block_size的值为3* 1048576=3145728字节
 

b.

创建临时文件

调用row_merge_file_create函数来对该数据的每个成员初始化临时文件。

单独建立一个临时文件tmpfd = row_merge_file_create_low();
 

c.

调用函数row_merge_read_clustered_index,读取聚集索引记录

一次scan 聚集索引,但为每一个要创建的索引创建entry,并将其加入到每个索引的sort buffer中(row_merge_buf_add)。

当buffer中的记录足够多时,就调用row_merge_buf_sort进行排序,并写入磁盘(row_merge_buf_write &&row_merge_write).

每个buffer的最大tuple数为:

max_tuples = sizeof(row_merge_block_t)/ ut_max(1, dict_index_get_min_size(index));
 


d.

现在我们可以对上一步准备好的临时文件或buffer进行排序。

排序函数为:
 

error = row_merge_sort(trx, indexes[i], &merge_files[i],

block, &tmpfd, table);
 

在row_merge_sort函数中,对刚刚产生的临时文件进行归并排序(row_merge)。

在5.5的MySQL中,这里存在一个Bug,归并排序存在问题(参阅MySQL官方 bug#54330上Jimmy yang的解释)

尽管Buglist中标注为已经fix,但事实上因为某些意外并没有merge到主干。Percona已经修复了这个问题(https://code.launchpad.net/~laurynas-biveinis/percona-server/bug54330/+merge/94510)
 

e.

排序完成后,调用row_merge_insert_index_tuples插入索引数据
 

f.

清理工作,及更新统计信息(如果开启了expand_fast_index_creation)

------分隔线----------------------------
标签(Tag):数据库 MYSQL mysql数据库
------分隔线----------------------------
推荐内容
猜你感兴趣