summaryrefslogtreecommitdiff
path: root/innobase/row
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/row')
-rw-r--r--innobase/row/row0ins.c7
-rw-r--r--innobase/row/row0mysql.c36
-rw-r--r--innobase/row/row0purge.c19
-rw-r--r--innobase/row/row0row.c19
-rw-r--r--innobase/row/row0sel.c10
-rw-r--r--innobase/row/row0umod.c18
-rw-r--r--innobase/row/row0upd.c30
-rw-r--r--innobase/row/row0vers.c2
8 files changed, 90 insertions, 51 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 92cac5a55cf..2c6d3b0ed00 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -277,7 +277,8 @@ row_ins_clust_index_entry_by_modify(
heap = mem_heap_create(1024);
/* Build an update vector containing all the fields to be modified;
- NOTE that this vector may contain also system columns! */
+ NOTE that this vector may NOT contain system columns trx_id or
+ roll_ptr */
update = row_upd_build_difference_binary(cursor->index, entry, ext_vec,
n_ext_vec, rec, heap);
@@ -1221,6 +1222,8 @@ row_ins_step(
trx = thr_get_trx(thr);
+ trx_start_if_not_started(trx);
+
node = thr->run_node;
ut_ad(que_node_get_type(node) == QUE_NODE_INSERT);
@@ -1241,8 +1244,6 @@ row_ins_step(
/* It may be that the current session has not yet started
its transaction, or it has been committed: */
- trx_start_if_not_started(trx);
-
if (UT_DULINT_EQ(trx->id, node->trx_id)) {
/* No need to do IX-locking or write trx id to buf */
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 13c0332dcef..59e2c08dfda 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -571,6 +571,8 @@ row_insert_for_mysql(
trx->op_info = "inserting";
+ trx_start_if_not_started(trx);
+
if (node == NULL) {
row_get_prebuilt_insert_row(prebuilt);
node = prebuilt->ins_node;
@@ -754,6 +756,8 @@ row_update_for_mysql(
trx->op_info = "updating or deleting";
+ trx_start_if_not_started(trx);
+
node = prebuilt->upd_node;
clust_index = dict_table_get_first_index(table);
@@ -947,6 +951,8 @@ row_create_table_for_mysql(
trx->op_info = "creating table";
+ trx_start_if_not_started(trx);
+
namelen = ut_strlen(table->name);
keywordlen = ut_strlen("innodb_monitor");
@@ -1077,6 +1083,8 @@ row_create_index_for_mysql(
trx->op_info = "creating index";
+ trx_start_if_not_started(trx);
+
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
@@ -1146,6 +1154,8 @@ row_table_add_foreign_constraints(
trx->op_info = "adding foreign keys";
+ trx_start_if_not_started(trx);
+
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
@@ -1218,6 +1228,8 @@ row_drop_table_for_mysql(
trx->op_info = "dropping table";
+ trx_start_if_not_started(trx);
+
namelen = ut_strlen(name);
keywordlen = ut_strlen("innodb_monitor");
@@ -1435,6 +1447,8 @@ row_drop_database_for_mysql(
trx->op_info = "dropping database";
+ trx_start_if_not_started(trx);
+
mutex_enter(&(dict_sys->mutex));
while (table_name = dict_get_first_table_name_in_db(name)) {
@@ -1496,6 +1510,7 @@ row_rename_table_for_mysql(
}
trx->op_info = "renaming table";
+ trx_start_if_not_started(trx);
str1 =
"PROCEDURE RENAME_TABLE_PROC () IS\n"
@@ -1602,6 +1617,7 @@ row_scan_and_check_index(
rec_t* rec;
ibool is_ok = TRUE;
int cmp;
+ char err_buf[1000];
*n_rows = 0;
@@ -1649,15 +1665,27 @@ loop:
if (cmp > 0) {
fprintf(stderr,
"Error: index records in a wrong order in index %s\n",
- index->name);
+ index->name);
+
+ dtuple_sprintf(err_buf, 900, prev_entry);
+ fprintf(stderr, "InnoDB: prev record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
is_ok = FALSE;
} else if ((index->type & DICT_UNIQUE)
&& matched_fields >=
dict_index_get_n_ordering_defined_by_user(index)) {
- fprintf(stderr,
- "Error: duplicate key in index %s\n",
- index->name);
+
+ fprintf(stderr, "Error: duplicate key in index %s\n",
+ index->name);
+
+ dtuple_sprintf(err_buf, 900, prev_entry);
+ fprintf(stderr, "InnoDB: prev record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
is_ok = FALSE;
}
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 0dffa273938..390f1b59a4d 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -208,7 +208,7 @@ row_purge_remove_sec_if_poss_low(
ibool found;
ulint err;
mtr_t mtr;
- mtr_t mtr_vers;
+ mtr_t* mtr_vers;
UT_NOT_USED(thr);
@@ -235,17 +235,21 @@ row_purge_remove_sec_if_poss_low(
which cannot be purged yet, requires its existence. If some requires,
we should do nothing. */
- mtr_start(&mtr_vers);
+ mtr_vers = mem_alloc(sizeof(mtr_t));
+
+ mtr_start(mtr_vers);
- success = row_purge_reposition_pcur(BTR_SEARCH_LEAF, node, &mtr_vers);
+ success = row_purge_reposition_pcur(BTR_SEARCH_LEAF, node, mtr_vers);
if (success) {
old_has = row_vers_old_has_index_entry(TRUE,
btr_pcur_get_rec(&(node->pcur)),
- &mtr_vers, index, entry);
+ mtr_vers, index, entry);
}
- btr_pcur_commit_specify_mtr(&(node->pcur), &mtr_vers);
+ btr_pcur_commit_specify_mtr(&(node->pcur), mtr_vers);
+
+ mem_free(mtr_vers);
if (!success || !old_has) {
/* Remove the index record */
@@ -489,11 +493,6 @@ row_purge_parse_undo_rec(
return(FALSE);
}
- /* NOTE that the table has to be explicitly released later */
-
- /* TODO: currently nothing prevents dropping of table when purge
- is accessing it! */
-
mutex_enter(&(dict_sys->mutex));
node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr));
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index 59169ef2a98..40a775143f4 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -455,12 +455,25 @@ row_build_row_ref_in_tuple(
ulint pos;
ulint i;
- ut_ad(ref && index && rec);
+ ut_a(ref && index && rec);
table = index->table;
+
+ if (!table) {
+ fprintf(stderr, "InnoDB: table %s for index %s not found\n",
+ index->table_name, index->name);
+ ut_a(0);
+ }
clust_index = dict_table_get_first_index(table);
-
+
+ if (!clust_index) {
+ fprintf(stderr,
+ "InnoDB: clust index for table %s for index %s not found\n",
+ index->table_name, index->name);
+ ut_a(0);
+ }
+
ref_len = dict_index_get_n_unique(clust_index);
ut_ad(ref_len == dtuple_get_n_fields(ref));
@@ -555,6 +568,8 @@ row_search_on_row_ref(
index = dict_table_get_first_index(table);
+ ut_a(dtuple_get_n_fields(ref) == dict_index_get_n_unique(index));
+
btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr);
low_match = btr_pcur_get_low_match(pcur);
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index e42486f1e17..2cccc217621 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -2671,6 +2671,8 @@ no_shortcut:
trx->has_search_latch = FALSE;
}
+ trx_start_if_not_started(trx);
+
/* Note that if the search mode was GE or G, then the cursor
naturally moves upward (in fetch next) in alphabetical order,
otherwise downward */
@@ -2715,16 +2717,12 @@ no_shortcut:
/* No need to set an intention lock or assign a read view */
} else if (prebuilt->select_lock_type == LOCK_NONE) {
- /* This is a consistent read */
- trx_start_if_not_started(trx);
-
+ /* This is a consistent read */
/* Assign a read view for the query */
trx_assign_read_view(trx);
prebuilt->sql_stat_start = FALSE;
- } else {
- trx_start_if_not_started(trx);
-
+ } else {
if (prebuilt->select_lock_type == LOCK_S) {
err = lock_table(0, index->table, LOCK_IS, thr);
} else {
diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c
index 37f5b1f0bc1..9e8ba87fc2f 100644
--- a/innobase/row/row0umod.c
+++ b/innobase/row/row0umod.c
@@ -299,13 +299,13 @@ row_undo_mod_del_mark_or_remove_sec_low(
BTR_MODIFY_TREE */
{
ibool found;
- mtr_t mtr;
- mtr_t mtr_vers;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
ibool success;
ibool old_has;
ulint err;
+ mtr_t mtr;
+ mtr_t mtr_vers;
log_free_check();
mtr_start(&mtr);
@@ -338,7 +338,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
- ut_ad(success);
+ ut_a(success);
old_has = row_vers_old_has_index_entry(FALSE,
btr_pcur_get_rec(&(node->pcur)),
@@ -361,7 +361,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
ut_ad(mode == BTR_MODIFY_TREE);
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
- TRUE, &mtr);
+ TRUE, &mtr);
/* The delete operation may fail if we have little
file space left: TODO: easiest to crash the database
@@ -413,12 +413,12 @@ row_undo_mod_del_unmark_sec(
dict_index_t* index, /* in: index */
dtuple_t* entry) /* in: index entry */
{
- mtr_t mtr;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
ulint err;
ibool found;
- char* err_buf;
+ mtr_t mtr;
+ char err_buf[1000];
UT_NOT_USED(node);
@@ -428,12 +428,10 @@ row_undo_mod_del_unmark_sec(
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
&mtr);
if (!found) {
- err_buf = mem_alloc(1000);
- dtuple_sprintf(err_buf, 900, entry);
-
fprintf(stderr, "InnoDB: error in sec index entry del undo in\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
+ dtuple_sprintf(err_buf, 900, entry);
fprintf(stderr, "InnoDB: tuple %s\n", err_buf);
rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur));
@@ -444,8 +442,6 @@ row_undo_mod_del_unmark_sec(
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
trx_print(thr_get_trx(thr));
-
- mem_free(err_buf);
} else {
btr_cur = btr_pcur_get_btr_cur(&pcur);
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index fa859729141..435cfa3485e 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -700,7 +700,7 @@ row_upd_build_difference_binary(
ulint i;
/* This function is used only for a clustered index */
- ut_ad(index->type & DICT_CLUSTERED);
+ ut_a(index->type & DICT_CLUSTERED);
update = upd_create(dtuple_get_n_fields(entry), heap);
@@ -718,10 +718,14 @@ row_upd_build_difference_binary(
/* NOTE: we compare the fields as binary strings!
(No collation) */
- if ((rec_get_nth_field_extern_bit(rec, i)
- != upd_ext_vec_contains(ext_vec, n_ext_vec, i))
- || ((i != trx_id_pos) && (i != roll_ptr_pos)
- && !dfield_data_is_binary_equal(dfield, len, data))) {
+ if (i == trx_id_pos || i == roll_ptr_pos) {
+
+ goto skip_compare;
+ }
+
+ if (rec_get_nth_field_extern_bit(rec, i)
+ != 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);
@@ -737,6 +741,8 @@ row_upd_build_difference_binary(
n_diff++;
}
+skip_compare:
+ ;
}
update->n_fields = n_diff;
@@ -1011,13 +1017,13 @@ row_upd_sec_index_entry(
ibool found;
dict_index_t* index;
dtuple_t* entry;
- mtr_t mtr;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
mem_heap_t* heap;
rec_t* rec;
- char* err_buf;
ulint err = DB_SUCCESS;
+ mtr_t mtr;
+ char err_buf[1000];
index = node->index;
@@ -1038,12 +1044,10 @@ row_upd_sec_index_entry(
rec = btr_cur_get_rec(btr_cur);
if (!found) {
- err_buf = mem_alloc(1000);
- dtuple_sprintf(err_buf, 900, entry);
-
fprintf(stderr, "InnoDB: error in sec index entry update in\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
+ dtuple_sprintf(err_buf, 900, entry);
fprintf(stderr, "InnoDB: tuple %s\n", err_buf);
rec_sprintf(err_buf, 900, rec);
@@ -1054,8 +1058,6 @@ row_upd_sec_index_entry(
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
trx_print(thr_get_trx(thr));
-
- mem_free(err_buf);
} else {
/* Delete mark the old index record; it can already be
delete marked if we return after a lock wait in
@@ -1620,6 +1622,8 @@ row_upd_step(
trx = thr_get_trx(thr);
+ trx_start_if_not_started(trx);
+
node = thr->run_node;
sel_node = node->select;
@@ -1638,8 +1642,6 @@ row_upd_step(
/* It may be that the current session has not yet
started its transaction, or it has been committed: */
- trx_start_if_not_started(thr_get_trx(thr));
-
err = lock_table(0, node->table, LOCK_IX, thr);
if (err != DB_SUCCESS) {
diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c
index 5b62cd2b7e3..9508e73f45d 100644
--- a/innobase/row/row0vers.c
+++ b/innobase/row/row0vers.c
@@ -300,7 +300,7 @@ row_vers_old_has_index_entry(
if heap2 != NULL */
}
- if ((err != DB_SUCCESS) || !prev_version) {
+ if (err != DB_SUCCESS || !prev_version) {
/* Versions end here */
mem_heap_free(heap);