返回首頁
當前位置: 主頁 > 網絡編程 > Php實例教程 >

[MySQL 源碼] innodb如何創建二級索引

時間:2012-08-30 15:56來源:知行網www.aotfjk.live 編輯:麥田守望者

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數據庫
------分隔線----------------------------
推薦內容
猜你感興趣
湖南刘雪龙黑彩