summaryrefslogtreecommitdiff
path: root/innobase/row/row0mysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row/row0mysql.c')
-rw-r--r--innobase/row/row0mysql.c98
1 files changed, 67 insertions, 31 deletions
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);