Commit e3d19b0f authored by marko's avatar marko

branches/zip: Fast index creation: Lock the data dictionary only after

acquiring the table lock.  The data dictionary should not be locked for
long periods.  Before this change, in the worst case, the dictionary
would be locked until the expiration of innodb_lock_wait_timeout.

Virtually, transaction-level locks (locks on database objects, such
as records and tables) have a latching order level of SYNC_USER_TRX_LOCK,
which is above any InnoDB rw-locks or mutexes.  However, the latching
order of SYNC_USER_TRX_LOCK is never checked, not even by UNIV_SYNC_DEBUG.

ha_innobase::add_index(), ha_innobase::final_drop_index(): Invoke
row_mysql_lock_data_dictionary(trx) only after row_merge_lock_table().
parent 463141d1
...@@ -693,12 +693,6 @@ err_exit: ...@@ -693,12 +693,6 @@ err_exit:
index = (dict_index_t**) mem_heap_alloc( index = (dict_index_t**) mem_heap_alloc(
heap, num_of_idx * sizeof *index); heap, num_of_idx * sizeof *index);
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
or lock waits can happen in it during an index create operation. */
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
/* Flag this transaction as a dictionary operation, so that /* Flag this transaction as a dictionary operation, so that
the data dictionary will be locked in crash recovery. Prevent the data dictionary will be locked in crash recovery. Prevent
warnings if row_merge_lock_table() results in a lock wait, warnings if row_merge_lock_table() results in a lock wait,
...@@ -717,6 +711,12 @@ err_exit: ...@@ -717,6 +711,12 @@ err_exit:
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
or lock waits can happen in it during an index create operation. */
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
/* If a new primary key is defined for the table we need /* If a new primary key is defined for the table we need
to drop the original table and rebuild all indexes. */ to drop the original table and rebuild all indexes. */
...@@ -1092,10 +1092,6 @@ ha_innobase::final_drop_index( ...@@ -1092,10 +1092,6 @@ ha_innobase::final_drop_index(
trx->mysql_thd = user_thd; trx->mysql_thd = user_thd;
trx->mysql_query_str = thd_query(user_thd); trx->mysql_query_str = thd_query(user_thd);
/* Drop indexes marked to be dropped */
row_mysql_lock_data_dictionary(trx);
/* Flag this transaction as a dictionary operation, so that /* Flag this transaction as a dictionary operation, so that
the data dictionary will be locked in crash recovery. Prevent the data dictionary will be locked in crash recovery. Prevent
warnings if row_merge_lock_table() results in a lock wait, warnings if row_merge_lock_table() results in a lock wait,
...@@ -1116,6 +1112,10 @@ ha_innobase::final_drop_index( ...@@ -1116,6 +1112,10 @@ ha_innobase::final_drop_index(
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
/* Drop indexes marked to be dropped */
row_mysql_lock_data_dictionary(trx);
index = dict_table_get_first_index(prebuilt->table); index = dict_table_get_first_index(prebuilt->table);
while (index) { while (index) {
...@@ -1134,10 +1134,10 @@ ha_innobase::final_drop_index( ...@@ -1134,10 +1134,10 @@ ha_innobase::final_drop_index(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
dict_table_check_for_dup_indexes(prebuilt->table); dict_table_check_for_dup_indexes(prebuilt->table);
#endif #endif
row_mysql_unlock_data_dictionary(trx);
func_exit: func_exit:
trx_commit_for_mysql(trx); trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
/* Flush the log to reduce probability that the .frm files and /* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs the InnoDB data dictionary get out-of-sync if the user runs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment