diff options
Diffstat (limited to 'innobase/row')
-rw-r--r-- | innobase/row/row0ins.c | 7 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 36 | ||||
-rw-r--r-- | innobase/row/row0purge.c | 19 | ||||
-rw-r--r-- | innobase/row/row0row.c | 19 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 10 | ||||
-rw-r--r-- | innobase/row/row0umod.c | 18 | ||||
-rw-r--r-- | innobase/row/row0upd.c | 30 | ||||
-rw-r--r-- | innobase/row/row0vers.c | 2 |
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); |