Commit 91295937 authored by marko's avatar marko

branches/zip: Simplify the locking of the data dictionary.

row_upd_index_is_referenced(), row_upd_check_references_constraints(),
row_purge_parse_undo_rec(): Remove duplicated code that calls
row_mysql_unfreeze_data_dictionary().

row_undo_ins_remove_clust_rec():
Assert that the data dictionary is X-latched.  Do not attempt to re-latch
the data dictionary, because doing so introduces race conditions.  This
re-latching was probably made unnecessary already in r1676, which keeps
the data dictionary X-latched in ha_innobase::add_index() for the complete
duration of the data dictionary operations.

row_undo_ins_parse_undo_rec(): Do not attempt to acquire the data dictionary
latch.  The data dictionary should be already X-latched when a transaction
that modifies system tables is rolled back.  This also holds in the rollback
during crash recovery: trx_rollback_active() will X-latch the data dictionary
when needed.
parent 63583d80
...@@ -526,9 +526,8 @@ row_purge_parse_undo_rec( ...@@ -526,9 +526,8 @@ row_purge_parse_undo_rec(
if (node->table == NULL) { if (node->table == NULL) {
/* The table has been dropped: no need to do purge */ /* The table has been dropped: no need to do purge */
err_exit:
row_mysql_unfreeze_data_dictionary(trx); row_mysql_unfreeze_data_dictionary(trx);
return(FALSE); return(FALSE);
} }
...@@ -537,9 +536,7 @@ row_purge_parse_undo_rec( ...@@ -537,9 +536,7 @@ row_purge_parse_undo_rec(
node->table = NULL; node->table = NULL;
row_mysql_unfreeze_data_dictionary(trx); goto err_exit;
return(FALSE);
} }
clust_index = dict_table_get_first_index(node->table); clust_index = dict_table_get_first_index(node->table);
...@@ -547,9 +544,7 @@ row_purge_parse_undo_rec( ...@@ -547,9 +544,7 @@ row_purge_parse_undo_rec(
if (clust_index == NULL) { if (clust_index == NULL) {
/* The table was corrupt in the data dictionary */ /* The table was corrupt in the data dictionary */
row_mysql_unfreeze_data_dictionary(trx); goto err_exit;
return(FALSE);
} }
ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref),
......
...@@ -53,24 +53,7 @@ row_undo_ins_remove_clust_rec( ...@@ -53,24 +53,7 @@ row_undo_ins_remove_clust_rec(
ut_a(success); ut_a(success);
if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) { if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
trx_t* trx; ut_ad(node->trx->dict_operation_lock_mode == RW_X_LATCH);
ibool thawed_dictionary = FALSE;
ibool locked_dictionary = FALSE;
trx = node->trx;
if (trx->dict_operation_lock_mode == RW_S_LATCH) {
row_mysql_unfreeze_data_dictionary(trx);
thawed_dictionary = TRUE;
}
if (trx->dict_operation_lock_mode != RW_X_LATCH) {
row_mysql_lock_data_dictionary(trx);
locked_dictionary = TRUE;
}
/* Drop the index tree associated with the row in /* Drop the index tree associated with the row in
SYS_INDEXES table: */ SYS_INDEXES table: */
...@@ -84,14 +67,6 @@ row_undo_ins_remove_clust_rec( ...@@ -84,14 +67,6 @@ row_undo_ins_remove_clust_rec(
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, success = btr_pcur_restore_position(BTR_MODIFY_LEAF,
&(node->pcur), &mtr); &(node->pcur), &mtr);
ut_a(success); ut_a(success);
if (locked_dictionary) {
row_mysql_unlock_data_dictionary(trx);
}
if (thawed_dictionary) {
row_mysql_freeze_data_dictionary(trx);
}
} }
btr_cur = btr_pcur_get_btr_cur(&(node->pcur)); btr_cur = btr_pcur_get_btr_cur(&(node->pcur));
...@@ -288,31 +263,7 @@ row_undo_ins_parse_undo_rec( ...@@ -288,31 +263,7 @@ row_undo_ins_parse_undo_rec(
if (node->rec_type == TRX_UNDO_INSERT_REC) { if (node->rec_type == TRX_UNDO_INSERT_REC) {
trx_t* trx; node->table = dict_table_get_on_id(table_id, node->trx);
ibool thawed_dictionary = FALSE;
ibool locked_dictionary = FALSE;
trx = node->trx;
/* If it is a system table, acquire the
dictionary lock in exclusive mode. */
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0) {
if (trx->dict_operation_lock_mode == RW_S_LATCH) {
row_mysql_unfreeze_data_dictionary(trx);
thawed_dictionary = TRUE;
}
if (trx->dict_operation_lock_mode != RW_X_LATCH) {
row_mysql_lock_data_dictionary(trx);
locked_dictionary = TRUE;
}
}
node->table = dict_table_get_on_id(table_id, trx);
/* If we can't find the table or .ibd file is missing, /* If we can't find the table or .ibd file is missing,
we skip the UNDO.*/ we skip the UNDO.*/
...@@ -327,14 +278,6 @@ row_undo_ins_parse_undo_rec( ...@@ -327,14 +278,6 @@ row_undo_ins_parse_undo_rec(
ptr = trx_undo_rec_get_row_ref( ptr = trx_undo_rec_get_row_ref(
ptr, clust_index, &node->ref, node->heap); ptr, clust_index, &node->ref, node->heap);
} }
if (locked_dictionary) {
row_mysql_unlock_data_dictionary(trx);
}
if (thawed_dictionary) {
row_mysql_freeze_data_dictionary(trx);
}
} }
} }
......
...@@ -107,6 +107,7 @@ row_upd_index_is_referenced( ...@@ -107,6 +107,7 @@ row_upd_index_is_referenced(
dict_table_t* table = index->table; dict_table_t* table = index->table;
dict_foreign_t* foreign; dict_foreign_t* foreign;
ibool froze_data_dict = FALSE; ibool froze_data_dict = FALSE;
ibool is_referenced = FALSE;
if (!UT_LIST_GET_FIRST(table->referenced_list)) { if (!UT_LIST_GET_FIRST(table->referenced_list)) {
...@@ -123,21 +124,19 @@ row_upd_index_is_referenced( ...@@ -123,21 +124,19 @@ row_upd_index_is_referenced(
while (foreign) { while (foreign) {
if (foreign->referenced_index == index) { if (foreign->referenced_index == index) {
if (froze_data_dict) { is_referenced = TRUE;
row_mysql_unfreeze_data_dictionary(trx); goto func_exit;
}
return(TRUE);
} }
foreign = UT_LIST_GET_NEXT(referenced_list, foreign); foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
} }
func_exit:
if (froze_data_dict) { if (froze_data_dict) {
row_mysql_unfreeze_data_dictionary(trx); row_mysql_unfreeze_data_dictionary(trx);
} }
return(FALSE); return(is_referenced);
} }
/************************************************************************* /*************************************************************************
...@@ -237,27 +236,24 @@ row_upd_check_references_constraints( ...@@ -237,27 +236,24 @@ row_upd_check_references_constraints(
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(
trx);
}
mem_heap_free(heap); goto func_exit;
return(err);
} }
} }
foreign = UT_LIST_GET_NEXT(referenced_list, foreign); foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
} }
err = DB_SUCCESS;
func_exit:
if (got_s_lock) { if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx); row_mysql_unfreeze_data_dictionary(trx);
} }
mem_heap_free(heap); mem_heap_free(heap);
return(DB_SUCCESS); return(err);
} }
/************************************************************************* /*************************************************************************
......
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