diff options
author | unknown <monty@hundin.mysql.fi> | 2002-04-25 01:16:42 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-04-25 01:16:42 +0300 |
commit | 0a03601fab2174e2a7590ff36d4ce2aee08adc5f (patch) | |
tree | 539e3f41736108728458d901c552313e5f058e8f /innobase/row/row0upd.c | |
parent | a56d1215f52b8d6ed9428b358034f439e03cbf5b (diff) | |
parent | 64cc56125791c5e3773399b6d3a40be81510b460 (diff) | |
download | mariadb-git-0a03601fab2174e2a7590ff36d4ce2aee08adc5f.tar.gz |
merge
BitKeeper/etc/logging_ok:
auto-union
configure.in:
Auto merged
BitKeeper/deleted/.del-identity.result~e41453a364242503:
Auto merged
BitKeeper/deleted/.del-identity.test~326f469b59105404:
Auto merged
include/my_pthread.h:
Auto merged
innobase/dict/dict0crea.c:
Auto merged
innobase/dict/dict0dict.c:
Auto merged
innobase/dict/dict0load.c:
Auto merged
innobase/include/univ.i:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
innobase/pars/pars0opt.c:
Auto merged
innobase/que/que0que.c:
Auto merged
innobase/row/row0ins.c:
Auto merged
innobase/row/row0mysql.c:
Auto merged
innobase/row/row0sel.c:
Auto merged
innobase/row/row0upd.c:
Auto merged
innobase/srv/srv0srv.c:
Auto merged
innobase/sync/sync0sync.c:
Auto merged
innobase/trx/trx0trx.c:
Auto merged
libmysql/libmysql.c:
Auto merged
myisam/myisampack.c:
Auto merged
mysql-test/t/func_test.test:
Auto merged
mysql-test/t/show_check.test:
Auto merged
mysql-test/t/variables.test:
Auto merged
mysys/my_pthread.c:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_func.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/share/danish/errmsg.txt:
Auto merged
sql/share/english/errmsg.txt:
Auto merged
sql/share/french/errmsg.txt:
Auto merged
sql/share/german/errmsg.txt:
Auto merged
sql/share/greek/errmsg.txt:
Auto merged
sql/share/hungarian/errmsg.txt:
Auto merged
sql/sql_show.cc:
Auto merged
sql/share/italian/errmsg.txt:
Auto merged
sql/share/japanese/errmsg.txt:
Auto merged
sql/share/korean/errmsg.txt:
Auto merged
sql/share/norwegian-ny/errmsg.txt:
Auto merged
sql/share/norwegian/errmsg.txt:
Auto merged
sql/share/polish/errmsg.txt:
Auto merged
sql/share/portuguese/errmsg.txt:
Auto merged
sql/share/romanian/errmsg.txt:
Auto merged
sql/share/russian/errmsg.txt:
Auto merged
sql/share/slovak/errmsg.txt:
Auto merged
sql/share/spanish/errmsg.txt:
Auto merged
sql/share/swedish/errmsg.txt:
Auto merged
sql/share/ukrainian/errmsg.txt:
Auto merged
Diffstat (limited to 'innobase/row/row0upd.c')
-rw-r--r-- | innobase/row/row0upd.c | 109 |
1 files changed, 75 insertions, 34 deletions
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 710f650c0bd..1d5319a182b 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -73,8 +73,7 @@ steps of query graph execution. */ /************************************************************************* Checks if index currently is mentioned as a referenced index in a foreign -key constraint. This function also loads into the dictionary cache the -possible referencing table. */ +key constraint. */ static ibool row_upd_index_is_referenced( @@ -85,44 +84,28 @@ row_upd_index_is_referenced( the referencing table has been dropped when we leave this function: this function is only for heuristic use! */ - dict_index_t* index) /* in: index */ + dict_index_t* index, /* in: index */ + trx_t* trx) /* in: transaction */ { - dict_table_t* table = index->table; + dict_table_t* table = index->table; dict_foreign_t* foreign; - ulint phase = 1; -try_again: if (!UT_LIST_GET_FIRST(table->referenced_list)) { return(FALSE); } - if (phase == 2) { - mutex_enter(&(dict_sys->mutex)); + if (!trx->has_dict_foreign_key_check_lock) { + rw_lock_s_lock(&dict_foreign_key_check_lock); } - rw_lock_s_lock(&dict_foreign_key_check_lock); - foreign = UT_LIST_GET_FIRST(table->referenced_list); while (foreign) { if (foreign->referenced_index == index) { - if (foreign->foreign_table == NULL) { - if (phase == 2) { - dict_table_get_low(foreign-> - foreign_table_name); - } else { - phase = 2; - rw_lock_s_unlock( - &dict_foreign_key_check_lock); - goto try_again; - } - } - - rw_lock_s_unlock(&dict_foreign_key_check_lock); - if (phase == 2) { - mutex_exit(&(dict_sys->mutex)); + if (!trx->has_dict_foreign_key_check_lock) { + rw_lock_s_unlock(&dict_foreign_key_check_lock); } return(TRUE); @@ -131,10 +114,8 @@ try_again: foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } - rw_lock_s_unlock(&dict_foreign_key_check_lock); - - if (phase == 2) { - mutex_exit(&(dict_sys->mutex)); + if (!trx->has_dict_foreign_key_check_lock) { + rw_lock_s_unlock(&dict_foreign_key_check_lock); } return(FALSE); @@ -160,8 +141,17 @@ row_upd_check_references_constraints( dict_foreign_t* foreign; mem_heap_t* heap; dtuple_t* entry; + trx_t* trx; rec_t* rec; ulint err; + ibool got_s_lock = FALSE; + + if (UT_LIST_GET_FIRST(table->referenced_list) == NULL) { + + return(DB_SUCCESS); + } + + trx = thr_get_trx(thr); rec = btr_pcur_get_rec(pcur); @@ -173,17 +163,61 @@ row_upd_check_references_constraints( mtr_start(mtr); - rw_lock_s_lock(&dict_foreign_key_check_lock); + if (!trx->has_dict_foreign_key_check_lock) { + got_s_lock = TRUE; + rw_lock_s_lock(&dict_foreign_key_check_lock); + + trx->has_dict_foreign_key_check_lock = TRUE; + } + foreign = UT_LIST_GET_FIRST(table->referenced_list); while (foreign) { if (foreign->referenced_index == index) { + if (foreign->foreign_table == NULL) { + dict_table_get(foreign->foreign_table_name, + trx); + } + if (foreign->foreign_table) { + mutex_enter(&(dict_sys->mutex)); + + (foreign->foreign_table + ->n_foreign_key_checks_running)++; + + mutex_exit(&(dict_sys->mutex)); + } + + /* NOTE that if the thread ends up waiting for a lock + we will release dict_foreign_key_check_lock + temporarily! But the counter on the table + protects 'foreign' from being dropped while the check + is running. */ + err = row_ins_check_foreign_constraint(FALSE, foreign, table, index, entry, thr); + + if (foreign->foreign_table) { + mutex_enter(&(dict_sys->mutex)); + + ut_a(foreign->foreign_table + ->n_foreign_key_checks_running > 0); + + (foreign->foreign_table + ->n_foreign_key_checks_running)--; + + mutex_exit(&(dict_sys->mutex)); + } + if (err != DB_SUCCESS) { - rw_lock_s_unlock(&dict_foreign_key_check_lock); + if (got_s_lock) { + rw_lock_s_unlock( + &dict_foreign_key_check_lock); + trx->has_dict_foreign_key_check_lock + = FALSE; + } + mem_heap_free(heap); return(err); @@ -193,7 +227,11 @@ row_upd_check_references_constraints( foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } - rw_lock_s_unlock(&dict_foreign_key_check_lock); + if (got_s_lock) { + rw_lock_s_unlock(&dict_foreign_key_check_lock); + trx->has_dict_foreign_key_check_lock = FALSE; + } + mem_heap_free(heap); return(DB_SUCCESS); @@ -222,6 +260,9 @@ upd_node_create( node->index = NULL; node->update = NULL; + node->cascade_heap = NULL; + node->cascade_node = NULL; + node->select = NULL; node->heap = mem_heap_create(128); @@ -1027,7 +1068,7 @@ row_upd_sec_index_entry( index = node->index; - check_ref = row_upd_index_is_referenced(index); + check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr)); heap = mem_heap_create(1024); @@ -1391,7 +1432,7 @@ row_upd_clust_step( index = dict_table_get_first_index(node->table); - check_ref = row_upd_index_is_referenced(index); + check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr)); pcur = node->pcur; |