diff options
author | unknown <heikki@hundin.mysql.fi> | 2002-11-06 00:41:27 +0200 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2002-11-06 00:41:27 +0200 |
commit | 444d8207d9a277231733dc6cd58bf21b626bba31 (patch) | |
tree | fed8334ab45443418d527c3837593e1121ed1975 /innobase/row | |
parent | 23f4865b163293006bbedbc2b69bc55ba1081baa (diff) | |
download | mariadb-git-444d8207d9a277231733dc6cd58bf21b626bba31.tar.gz |
Many files:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
sql/ha_innodb.cc:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/dict/dict0crea.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/dict/dict0dict.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/log0recv.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/row0mysql.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/srv0srv.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/include/trx0trx.h:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/log/log0recv.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/os/os0sync.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/os/os0thread.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0ins.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0mysql.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0purge.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0undo.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/row/row0upd.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/srv/srv0srv.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/srv/srv0start.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/trx/trx0roll.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
innobase/trx/trx0trx.c:
Merge InnoDB-4.0.5b: minor improvements to foreign keys, more logical data dictionary lock
Diffstat (limited to 'innobase/row')
-rw-r--r-- | innobase/row/row0ins.c | 13 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 98 | ||||
-rw-r--r-- | innobase/row/row0purge.c | 30 | ||||
-rw-r--r-- | innobase/row/row0undo.c | 20 | ||||
-rw-r--r-- | innobase/row/row0upd.c | 28 |
5 files changed, 113 insertions, 76 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 4e8b487a0f1..d0a5cfec604 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -643,7 +643,7 @@ row_ins_check_foreign_constraint( run_again: ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_SHARED)); - + err = DB_SUCCESS; if (thr_get_trx(thr)->check_foreigns == FALSE) { @@ -880,21 +880,16 @@ row_ins_check_foreign_constraints( trx); } - if (!trx->has_dict_operation_lock) { + if (0 == trx->dict_operation_lock_mode) { got_s_lock = TRUE; - rw_lock_s_lock(&dict_operation_lock); - - trx->has_dict_operation_lock = TRUE; + row_mysql_freeze_data_dictionary(trx); } err = row_ins_check_foreign_constraint(TRUE, foreign, table, index, entry, thr); if (got_s_lock) { - - rw_lock_s_unlock(&dict_operation_lock); - - trx->has_dict_operation_lock = FALSE; + row_mysql_unfreeze_data_dictionary(trx); } if (err != DB_SUCCESS) { diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 6fde57eb75a..b109b785a45 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1134,32 +1134,73 @@ row_mysql_recover_tmp_table( } /************************************************************************* -Locks the data dictionary exclusively for performing a table create -operation. */ +Locks the data dictionary in shared mode from modifications, for performing +foreign key check, rollback, or other operation invisible to MySQL. */ void -row_mysql_lock_data_dictionary(void) -/*================================*/ +row_mysql_freeze_data_dictionary( +/*=============================*/ + trx_t* trx) /* in: transaction */ +{ + ut_a(trx->dict_operation_lock_mode == 0); + + rw_lock_s_lock(&dict_operation_lock); + + trx->dict_operation_lock_mode = RW_S_LATCH; +} + +/************************************************************************* +Unlocks the data dictionary shared lock. */ + +void +row_mysql_unfreeze_data_dictionary( +/*===============================*/ + trx_t* trx) /* in: transaction */ { + ut_a(trx->dict_operation_lock_mode == RW_S_LATCH); + + rw_lock_s_unlock(&dict_operation_lock); + + trx->dict_operation_lock_mode = 0; +} + +/************************************************************************* +Locks the data dictionary exclusively for performing a table create or other +data dictionary modification operation. */ + +void +row_mysql_lock_data_dictionary( +/*===========================*/ + trx_t* trx) /* in: transaction */ +{ + ut_a(trx->dict_operation_lock_mode == 0); + /* Serialize data dictionary operations with dictionary mutex: no deadlocks or lock waits can occur then in these operations */ rw_lock_x_lock(&dict_operation_lock); + trx->dict_operation_lock_mode = RW_X_LATCH; + mutex_enter(&(dict_sys->mutex)); } /************************************************************************* -Unlocks the data dictionary exclusively lock. */ +Unlocks the data dictionary exclusive lock. */ void -row_mysql_unlock_data_dictionary(void) -/*==================================*/ +row_mysql_unlock_data_dictionary( +/*=============================*/ + trx_t* trx) /* in: transaction */ { + ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ mutex_exit(&(dict_sys->mutex)); rw_lock_x_unlock(&dict_operation_lock); + + trx->dict_operation_lock_mode = 0; } /************************************************************************* @@ -1183,6 +1224,7 @@ row_create_table_for_mysql( ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); + ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(mutex_own(&(dict_sys->mutex))); if (srv_created_new_raw) { @@ -1331,7 +1373,7 @@ row_create_table_for_mysql( fprintf(stderr, "InnoDB: Warning: cannot create table %s because tablespace full\n", table->name); - row_drop_table_for_mysql(table->name, trx, TRUE); + row_drop_table_for_mysql(table->name, trx); } else { ut_a(err == DB_DUPLICATE_KEY); @@ -1425,7 +1467,7 @@ row_create_index_for_mysql( trx_general_rollback_for_mysql(trx, FALSE, NULL); - row_drop_table_for_mysql(index->table_name, trx, TRUE); + row_drop_table_for_mysql(index->table_name, trx); trx->error_state = DB_SUCCESS; } @@ -1499,7 +1541,7 @@ row_table_add_foreign_constraints( trx_general_rollback_for_mysql(trx, FALSE, NULL); - row_drop_table_for_mysql(name, trx, TRUE); + row_drop_table_for_mysql(name, trx); trx->error_state = DB_SUCCESS; } @@ -1530,7 +1572,7 @@ row_drop_table_for_mysql_in_background( name); */ /* Drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx); if (error != DB_SUCCESS) { fprintf(stderr, @@ -1689,9 +1731,7 @@ row_drop_table_for_mysql( /*=====================*/ /* out: error code or DB_SUCCESS */ char* name, /* in: table name */ - trx_t* trx, /* in: transaction handle */ - ibool has_dict_mutex) /* in: TRUE if the caller already owns the - dictionary system mutex */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; que_thr_t* thr; @@ -1703,6 +1743,7 @@ row_drop_table_for_mysql( ulint namelen; ulint keywordlen; ulint rounds = 0; + ibool locked_dictionary = FALSE; char buf[10000]; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1846,12 +1887,13 @@ row_drop_table_for_mysql( /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ - if (!has_dict_mutex) { + if (trx->dict_operation_lock_mode != RW_X_LATCH) { /* Prevent foreign key checks etc. while we are dropping the table */ - rw_lock_x_lock(&dict_operation_lock); - mutex_enter(&(dict_sys->mutex)); + row_mysql_lock_data_dictionary(trx); + + locked_dictionary = TRUE; } ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1948,9 +1990,8 @@ row_drop_table_for_mysql( } funct_exit: - if (!has_dict_mutex) { - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&dict_operation_lock); + if (locked_dictionary) { + row_mysql_unlock_data_dictionary(trx); } que_graph_free(graph); @@ -1986,8 +2027,7 @@ row_drop_database_for_mysql( trx_start_if_not_started(trx); loop: - rw_lock_x_lock(&dict_operation_lock); - mutex_enter(&(dict_sys->mutex)); + row_mysql_lock_data_dictionary(trx); while ((table_name = dict_get_first_table_name_in_db(name))) { ut_a(memcmp(table_name, name, strlen(name)) == 0); @@ -2000,8 +2040,7 @@ loop: the table */ if (table->n_mysql_handles_opened > 0) { - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&dict_operation_lock); + row_mysql_unlock_data_dictionary(trx); ut_print_timestamp(stderr); fprintf(stderr, @@ -2016,7 +2055,7 @@ loop: goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx); mem_free(table_name); @@ -2028,8 +2067,7 @@ loop: } } - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&dict_operation_lock); + row_mysql_unlock_data_dictionary(trx); trx_commit_for_mysql(trx); @@ -2166,8 +2204,7 @@ row_rename_table_for_mysql( /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ - rw_lock_x_lock(&dict_operation_lock); - mutex_enter(&(dict_sys->mutex)); + row_mysql_lock_data_dictionary(trx); table = dict_table_get_low(old_name); @@ -2249,8 +2286,7 @@ row_rename_table_for_mysql( } } funct_exit: - mutex_exit(&(dict_sys->mutex)); - rw_lock_x_unlock(&dict_operation_lock); + row_mysql_unlock_data_dictionary(trx); que_graph_free(graph); diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 3d9ae6aad8b..b64003f22d4 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -24,6 +24,7 @@ Created 3/14/1997 Heikki Tuuri #include "row0row.h" #include "row0upd.h" #include "row0vers.h" +#include "row0mysql.h" #include "log0log.h" /************************************************************************ @@ -454,8 +455,8 @@ ibool row_purge_parse_undo_rec( /*=====================*/ /* out: TRUE if purge operation required: - NOTE that then the CALLER must s-unlock - dict_operation_lock! */ + NOTE that then the CALLER must unfreeze + data dictionary! */ purge_node_t* node, /* in: row undo node */ ibool* updated_extern, /* out: TRUE if an externally stored field @@ -464,6 +465,7 @@ row_purge_parse_undo_rec( { dict_index_t* clust_index; byte* ptr; + trx_t* trx; dulint undo_no; dulint table_id; dulint trx_id; @@ -473,6 +475,8 @@ row_purge_parse_undo_rec( ulint cmpl_info; ut_ad(node && thr); + + trx = thr_get_trx(thr); ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info, updated_extern, &undo_no, &table_id); @@ -498,17 +502,18 @@ row_purge_parse_undo_rec( /* Prevent DROP TABLE etc. from running when we are doing the purge for this row */ - rw_lock_s_lock(&dict_operation_lock); - mutex_enter(&(dict_sys->mutex)); + row_mysql_freeze_data_dictionary(trx); - node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); + mutex_enter(&(dict_sys->mutex)); - mutex_exit(&(dict_sys->mutex)); + node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); + mutex_exit(&(dict_sys->mutex)); + if (node->table == NULL) { /* The table has been dropped: no need to do purge */ - rw_lock_s_unlock(&dict_operation_lock); + row_mysql_unfreeze_data_dictionary(trx); return(FALSE); } @@ -518,7 +523,7 @@ row_purge_parse_undo_rec( if (clust_index == NULL) { /* The table was corrupt in the data dictionary */ - rw_lock_s_unlock(&dict_operation_lock); + row_mysql_unfreeze_data_dictionary(trx); return(FALSE); } @@ -556,9 +561,12 @@ row_purge( dulint roll_ptr; ibool purge_needed; ibool updated_extern; + trx_t* trx; ut_ad(node && thr); + trx = thr_get_trx(thr); + node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr, &(node->reservation), node->heap); @@ -577,8 +585,8 @@ row_purge( } else { purge_needed = row_purge_parse_undo_rec(node, &updated_extern, thr); - /* If purge_needed == TRUE, we must also remember to unlock - dict_operation_lock! */ + /* If purge_needed == TRUE, we must also remember to unfreeze + data dictionary! */ } if (purge_needed) { @@ -600,7 +608,7 @@ row_purge( btr_pcur_close(&(node->pcur)); } - rw_lock_s_unlock(&dict_operation_lock); + row_mysql_unfreeze_data_dictionary(trx); } /* Do some cleanup */ diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index 6f1cfc4db9f..01b0b1ab41e 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -24,6 +24,7 @@ Created 1/8/1997 Heikki Tuuri #include "row0row.h" #include "row0uins.h" #include "row0umod.h" +#include "row0mysql.h" #include "srv0srv.h" /* How to undo row operations? @@ -204,6 +205,7 @@ row_undo( ulint err; trx_t* trx; dulint roll_ptr; + ibool froze_data_dict = FALSE; ut_ad(node && thr); @@ -256,13 +258,13 @@ row_undo( /* Prevent DROP TABLE etc. while we are rolling back this row. If we are doing a TABLE CREATE or some other dictionary operation, then we already have dict_operation_lock locked in x-mode. Do not - try to lock again in s-mode, because that would cause a hang. - - TODO: keep track when trx exactly has the latch locked!!! - TODO: trx->dict_operation tells it only in some cases!!! */ - - if (!trx->dict_operation) { - rw_lock_s_lock(&dict_operation_lock); + try to lock again in s-mode, because that would cause a hang. */ + + if (trx->dict_operation_lock_mode == 0) { + + row_mysql_freeze_data_dictionary(trx); + + froze_data_dict = TRUE; } if (node->state == UNDO_NODE_INSERT) { @@ -275,9 +277,9 @@ row_undo( err = row_undo_mod(node, thr); } - if (!trx->dict_operation) { + if (froze_data_dict) { - rw_lock_s_unlock(&dict_operation_lock); + row_mysql_unfreeze_data_dictionary(trx); } /* Do some cleanup */ diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 0be4f901d16..1231c94da63 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -89,14 +89,16 @@ row_upd_index_is_referenced( { dict_table_t* table = index->table; dict_foreign_t* foreign; + ibool froze_data_dict = FALSE; if (!UT_LIST_GET_FIRST(table->referenced_list)) { return(FALSE); } - if (!trx->has_dict_operation_lock) { - rw_lock_s_lock(&dict_operation_lock); + if (trx->dict_operation_lock_mode == 0) { + row_mysql_freeze_data_dictionary(trx); + froze_data_dict = TRUE; } foreign = UT_LIST_GET_FIRST(table->referenced_list); @@ -104,8 +106,8 @@ row_upd_index_is_referenced( while (foreign) { if (foreign->referenced_index == index) { - if (!trx->has_dict_operation_lock) { - rw_lock_s_unlock(&dict_operation_lock); + if (froze_data_dict) { + row_mysql_unfreeze_data_dictionary(trx); } return(TRUE); @@ -114,8 +116,8 @@ row_upd_index_is_referenced( foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } - if (!trx->has_dict_operation_lock) { - rw_lock_s_unlock(&dict_operation_lock); + if (froze_data_dict) { + row_mysql_unfreeze_data_dictionary(trx); } return(FALSE); @@ -162,12 +164,10 @@ row_upd_check_references_constraints( mtr_start(mtr); - if (!trx->has_dict_operation_lock) { + if (trx->dict_operation_lock_mode == 0) { got_s_lock = TRUE; - rw_lock_s_lock(&dict_operation_lock); - - trx->has_dict_operation_lock = TRUE; + row_mysql_freeze_data_dictionary(trx); } foreign = UT_LIST_GET_FIRST(table->referenced_list); @@ -211,10 +211,7 @@ row_upd_check_references_constraints( if (err != DB_SUCCESS) { if (got_s_lock) { - rw_lock_s_unlock( - &dict_operation_lock); - trx->has_dict_operation_lock - = FALSE; + row_mysql_unfreeze_data_dictionary(trx); } mem_heap_free(heap); @@ -227,8 +224,7 @@ row_upd_check_references_constraints( } if (got_s_lock) { - rw_lock_s_unlock(&dict_operation_lock); - trx->has_dict_operation_lock = FALSE; + row_mysql_unfreeze_data_dictionary(trx); } mem_heap_free(heap); |