summaryrefslogtreecommitdiff
path: root/innobase/row
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2002-11-06 00:41:27 +0200
committerunknown <heikki@hundin.mysql.fi>2002-11-06 00:41:27 +0200
commit444d8207d9a277231733dc6cd58bf21b626bba31 (patch)
treefed8334ab45443418d527c3837593e1121ed1975 /innobase/row
parent23f4865b163293006bbedbc2b69bc55ba1081baa (diff)
downloadmariadb-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.c13
-rw-r--r--innobase/row/row0mysql.c98
-rw-r--r--innobase/row/row0purge.c30
-rw-r--r--innobase/row/row0undo.c20
-rw-r--r--innobase/row/row0upd.c28
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);