summaryrefslogtreecommitdiff
path: root/innobase/row
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row')
-rw-r--r--innobase/row/row0ins.c24
-rw-r--r--innobase/row/row0mysql.c70
-rw-r--r--innobase/row/row0purge.c8
-rw-r--r--innobase/row/row0upd.c23
4 files changed, 80 insertions, 45 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index b28be55347c..bbec004176b 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -609,7 +609,7 @@ the caller must have a shared latch on dict_foreign_key_check_lock. */
ulint
row_ins_check_foreign_constraint(
/*=============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
+ /* out: DB_SUCCESS,
DB_NO_REFERENCED_ROW,
or DB_ROW_IS_REFERENCED */
ibool check_ref,/* in: TRUE if we want to check that
@@ -635,6 +635,7 @@ row_ins_check_foreign_constraint(
ulint i;
mtr_t mtr;
+run_again:
ut_ad(rw_lock_own(&dict_foreign_key_check_lock, RW_LOCK_SHARED));
if (thr_get_trx(thr)->check_foreigns == FALSE) {
@@ -682,7 +683,7 @@ row_ins_check_foreign_constraint(
if (err != DB_SUCCESS) {
- return(err);
+ goto do_possible_lock_wait;
}
}
@@ -727,6 +728,11 @@ row_ins_check_foreign_constraint(
if (!rec_get_deleted_flag(rec)) {
/* Found a matching record */
+/* printf(
+"FOREIGN: Found matching record from %s %s\n",
+ check_index->table_name, check_index->name);
+ rec_print(rec);
+*/
if (check_ref) {
err = DB_SUCCESS;
@@ -779,6 +785,17 @@ next_rec:
/* Restore old value */
dtuple_set_n_fields_cmp(entry, n_fields_cmp);
+do_possible_lock_wait:
+ if (err == DB_LOCK_WAIT) {
+ thr_get_trx(thr)->error_state = err;
+
+ que_thr_stop_for_mysql(thr);
+
+ row_mysql_handle_errors(&err, thr_get_trx(thr), thr, NULL);
+
+ goto run_again;
+ }
+
return(err);
}
@@ -792,8 +809,7 @@ static
ulint
row_ins_check_foreign_constraints(
/*==============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- code */
+ /* out: DB_SUCCESS or error code */
dict_table_t* table, /* in: table */
dict_index_t* index, /* in: index */
dtuple_t* entry, /* in: index entry for index */
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 1dfb1c4ee77..b05476e0a3d 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -934,6 +934,7 @@ row_update_for_mysql(
ut_ad(!prebuilt->sql_stat_start);
que_thr_move_to_run_state_for_mysql(thr, trx);
+
run_again:
thr->run_node = node;
thr->prev_node = node;
@@ -998,7 +999,6 @@ row_update_cascade_for_mysql(
trx_t* trx;
trx = thr_get_trx(thr);
-
run_again:
thr->run_node = node;
thr->prev_node = node;
@@ -1131,6 +1131,35 @@ row_mysql_recover_tmp_table(
}
/*************************************************************************
+Locks the data dictionary exclusively for performing a table create
+operation. */
+
+void
+row_mysql_lock_data_dictionary(void)
+/*================================*/
+{
+ /* Serialize data dictionary operations with dictionary mutex:
+ no deadlocks or lock waits can occur then in these operations */
+
+ rw_lock_x_lock(&(dict_foreign_key_check_lock));
+ mutex_enter(&(dict_sys->mutex));
+}
+
+/*************************************************************************
+Unlocks the data dictionary exclusively lock. */
+
+void
+row_mysql_unlock_data_dictionary(void)
+/*==================================*/
+{
+ /* 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_foreign_key_check_lock));
+}
+
+/*************************************************************************
Does a table creation operation for MySQL. If the name of the created
table ends to characters INNODB_MONITOR, then this also starts
printing of monitor output by the master thread. */
@@ -1150,6 +1179,7 @@ row_create_table_for_mysql(
ulint err;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
+ ut_ad(mutex_own(&(dict_sys->mutex)));
if (srv_created_new_raw || srv_force_recovery) {
fprintf(stderr,
@@ -1263,19 +1293,13 @@ row_create_table_for_mysql(
"to use this feature you must compile InnoDB with\n"
"UNIV_MEM_DEBUG defined in univ.i and the server must be\n"
"quiet because allocation from a mem heap is not protected\n"
- "by any semaphore.\n");
+ "by any semaphore.\n");
ut_a(mem_validate());
printf("Memory validated\n");
}
- /* Serialize data dictionary operations with dictionary mutex:
- no deadlocks can occur then in these operations */
-
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
- mutex_enter(&(dict_sys->mutex));
-
heap = mem_heap_create(512);
trx->dict_operation = TRUE;
@@ -1325,9 +1349,6 @@ row_create_table_for_mysql(
trx->error_state = DB_SUCCESS;
}
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
-
que_graph_free((que_t*) que_node_get_parent(thr));
trx->op_info = "";
@@ -1354,6 +1375,7 @@ row_create_index_for_mysql(
ulint keywordlen;
ulint err;
+ ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
trx->op_info = "creating index";
@@ -1372,12 +1394,6 @@ row_create_index_for_mysql(
return(DB_SUCCESS);
}
- /* Serialize data dictionary operations with dictionary mutex:
- no deadlocks can occur then in these operations */
-
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
- mutex_enter(&(dict_sys->mutex));
-
heap = mem_heap_create(512);
trx->dict_operation = TRUE;
@@ -1405,9 +1421,6 @@ row_create_index_for_mysql(
trx->error_state = DB_SUCCESS;
}
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
-
que_graph_free((que_t*) que_node_get_parent(thr));
trx->op_info = "";
@@ -1441,6 +1454,7 @@ row_table_add_foreign_constraints(
ulint keywordlen;
ulint err;
+ ut_ad(mutex_own(&(dict_sys->mutex)));
ut_a(sql_string);
trx->op_info = "adding foreign keys";
@@ -1459,12 +1473,6 @@ row_table_add_foreign_constraints(
return(DB_SUCCESS);
}
- /* Serialize data dictionary operations with dictionary mutex:
- no deadlocks can occur then in these operations */
-
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
- mutex_enter(&(dict_sys->mutex));
-
trx->dict_operation = TRUE;
err = dict_create_foreign_constraints(trx, sql_string, name);
@@ -1486,9 +1494,6 @@ row_table_add_foreign_constraints(
trx->error_state = DB_SUCCESS;
}
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
-
return((int) err);
}
@@ -1917,6 +1922,13 @@ row_drop_table_for_mysql(
ut_a(0);
} else {
dict_table_remove_from_cache(table);
+
+ if (dict_load_table(name) != NULL) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: dropping of table %s failed!\n", name);
+
+ }
}
funct_exit:
rw_lock_s_unlock(&(purge_sys->purge_is_running));
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 390f1b59a4d..5da98943926 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -511,6 +511,14 @@ row_purge_parse_undo_rec(
clust_index = dict_table_get_first_index(node->table);
+ if (clust_index == NULL) {
+ /* The table was corrupt in the data dictionary */
+
+ rw_lock_x_unlock(&(purge_sys->purge_is_running));
+
+ return(FALSE);
+ }
+
ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref),
node->heap);
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 457cb72aaad..77af2390786 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -129,8 +129,7 @@ static
ulint
row_upd_check_references_constraints(
/*=================================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or an error
- code */
+ /* out: DB_SUCCESS or an error code */
btr_pcur_t* pcur, /* in: cursor positioned on a record; NOTE: the
cursor position is lost in this function! */
dict_table_t* table, /* in: table in question */
@@ -626,7 +625,7 @@ row_upd_index_parse(
/*******************************************************************
Returns TRUE if ext_vec contains i. */
-UNIV_INLINE
+static
ibool
upd_ext_vec_contains(
/*=================*/
@@ -738,6 +737,7 @@ row_upd_build_difference_binary(
ulint n_diff;
ulint roll_ptr_pos;
ulint trx_id_pos;
+ ibool extern_bit;
ulint i;
/* This function is used only for a clustered index */
@@ -763,9 +763,10 @@ row_upd_build_difference_binary(
goto skip_compare;
}
+
+ extern_bit = rec_get_nth_field_extern_bit(rec, i);
- if (rec_get_nth_field_extern_bit(rec, i)
- != upd_ext_vec_contains(ext_vec, n_ext_vec, i)
+ if (extern_bit != upd_ext_vec_contains(ext_vec, n_ext_vec, i)
|| !dfield_data_is_binary_equal(dfield, len, data)) {
upd_field = upd_get_nth_field(update, n_diff);
@@ -1362,7 +1363,7 @@ ulint
row_upd_del_mark_clust_rec(
/*=======================*/
/* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
+ completed, else error code */
upd_node_t* node, /* in: row update node */
dict_index_t* index, /* in: clustered index */
que_thr_t* thr, /* in: query thread */
@@ -1381,8 +1382,6 @@ row_upd_del_mark_clust_rec(
pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur);
- ut_ad(FALSE == rec_get_deleted_flag(btr_pcur_get_rec(pcur)));
-
/* Store row because we have to build also the secondary index
entries */
@@ -1391,11 +1390,11 @@ row_upd_del_mark_clust_rec(
/* Mark the clustered index record deleted; we do not have to check
locks, because we assume that we have an x-lock on the record */
- err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, btr_cur,
- TRUE, thr, mtr);
+ err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
+ btr_cur, TRUE, thr, mtr);
if (err == DB_SUCCESS && check_ref) {
- /* NOTE that the following call loses
- the position of pcur ! */
+ /* NOTE that the following call loses the position of pcur ! */
+
err = row_upd_check_references_constraints(pcur, index->table,
index, thr, mtr);
if (err != DB_SUCCESS) {