diff options
Diffstat (limited to 'storage/xtradb/row/row0mysql.c')
-rw-r--r-- | storage/xtradb/row/row0mysql.c | 134 |
1 files changed, 78 insertions, 56 deletions
diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index e520065ea04..62221fa456d 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -30,6 +30,7 @@ Created 9/17/2000 Heikki Tuuri #include "row0mysql.ic" #endif +#include "ha_prototypes.h" #include "row0ins.h" #include "row0merge.h" #include "row0sel.h" @@ -522,6 +523,7 @@ handle_new_error: case DB_CANNOT_ADD_CONSTRAINT: case DB_TOO_MANY_CONCURRENT_TRXS: case DB_OUT_OF_FILE_SPACE: + case DB_INTERRUPTED: if (savept) { /* Roll back the latest, possibly incomplete insertion or update */ @@ -624,6 +626,8 @@ row_create_prebuilt( prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = 99999999; + UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type, + sizeof prebuilt->stored_select_lock_type); prebuilt->search_tuple = dtuple_create( heap, 2 * dict_table_get_n_cols(table)); @@ -864,7 +868,7 @@ row_update_statistics_if_needed( if (counter > 2000000000 || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) { - dict_update_statistics(table); + dict_update_statistics(table, TRUE); } } @@ -1124,6 +1128,13 @@ row_insert_for_mysql( thr = que_fork_get_first_thr(prebuilt->ins_graph); + if (!prebuilt->mysql_has_locked) { + fprintf(stderr, "InnoDB: Error: row_insert_for_mysql is called without ha_innobase::external_lock()\n"); + if (trx->mysql_thd != NULL) { + innobase_mysql_print_thd(stderr, trx->mysql_thd, 600); + } + } + if (prebuilt->sql_stat_start) { node->state = INS_NODE_SET_IX_LOCK; prebuilt->sql_stat_start = FALSE; @@ -1430,27 +1441,26 @@ run_again: } /*********************************************************************//** -This can only be used when srv_locks_unsafe_for_binlog is TRUE or -this session is using a READ COMMITTED isolation level. Before -calling this function we must use trx_reset_new_rec_lock_info() and -trx_register_new_rec_lock() to store the information which new record locks -really were set. This function removes a newly set lock under prebuilt->pcur, -and also under prebuilt->clust_pcur. Currently, this is only used and tested -in the case of an UPDATE or a DELETE statement, where the row lock is of the -LOCK_X type. -Thus, this implements a 'mini-rollback' that releases the latest record -locks we set. -@return error code or DB_SUCCESS */ +This can only be used when srv_locks_unsafe_for_binlog is TRUE or this +session is using a READ COMMITTED or READ UNCOMMITTED isolation level. +Before calling this function row_search_for_mysql() must have +initialized prebuilt->new_rec_locks to store the information which new +record locks really were set. This function removes a newly set +clustered index record lock under prebuilt->pcur or +prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that +releases the latest clustered index record lock we set. +@return error code or DB_SUCCESS */ UNIV_INTERN int row_unlock_for_mysql( /*=================*/ - row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL + row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL handle */ - ibool has_latches_on_recs)/*!< TRUE if called so that we have - the latches on the records under pcur - and clust_pcur, and we do not need to - reposition the cursors. */ + ibool has_latches_on_recs)/*!< in: TRUE if called so + that we have the latches on + the records under pcur and + clust_pcur, and we do not need + to reposition the cursors. */ { btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* clust_pcur = prebuilt->clust_pcur; @@ -1648,37 +1658,6 @@ row_table_got_default_clust_index( } /*********************************************************************//** -Calculates the key number used inside MySQL for an Innobase index. We have -to take into account if we generated a default clustered index for the table -@return the key number used inside MySQL */ -UNIV_INTERN -ulint -row_get_mysql_key_number_for_index( -/*===============================*/ - const dict_index_t* index) /*!< in: index */ -{ - const dict_index_t* ind; - ulint i; - - ut_a(index); - - i = 0; - ind = dict_table_get_first_index(index->table); - - while (index != ind) { - ind = dict_table_get_next_index(ind); - i++; - } - - if (row_table_got_default_clust_index(index->table)) { - ut_a(i > 0); - i--; - } - - return(i); -} - -/*********************************************************************//** Locks the data dictionary in shared mode from modifications, for performing foreign key check, rollback, or other operation invisible to MySQL. */ UNIV_INTERN @@ -2044,6 +2023,45 @@ error_handling: } /*********************************************************************//** +*/ +UNIV_INTERN +int +row_insert_stats_for_mysql( +/*=======================*/ + dict_index_t* index, + trx_t* trx) +{ + ind_node_t* node; + mem_heap_t* heap; + que_thr_t* thr; + ulint err; + + ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + + trx->op_info = "try to insert rows to SYS_STATS"; + + trx_start_if_not_started(trx); + trx->error_state = DB_SUCCESS; + + heap = mem_heap_create(512); + + node = ind_insert_stats_graph_create(index, heap); + + thr = pars_complete_graph_for_exec(node, trx, heap); + + ut_a(thr == que_fork_start_command(que_node_get_parent(thr))); + que_run_threads(thr); + + err = trx->error_state; + + que_graph_free((que_t*) que_node_get_parent(thr)); + + trx->op_info = ""; + + return((int) err); +} + +/*********************************************************************//** Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function should be called after the indexes for a table have been created. @@ -2062,6 +2080,7 @@ row_table_add_foreign_constraints( FOREIGN KEY (a, b) REFERENCES table2(c, d), table2 can be written also with the database name before it: test.table2 */ + size_t sql_length, /*!< in: length of sql_string */ const char* name, /*!< in: table full name in the normalized form database_name/table_name */ @@ -2083,8 +2102,8 @@ row_table_add_foreign_constraints( trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); - err = dict_create_foreign_constraints(trx, sql_string, name, - reject_fks); + err = dict_create_foreign_constraints(trx, sql_string, sql_length, + name, reject_fks); if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ err = dict_load_foreigns(name, TRUE); @@ -2428,7 +2447,7 @@ row_discard_tablespace_for_mysql( goto funct_exit; } - new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); + dict_hdr_get_new_id(&new_id, NULL, NULL); /* Remove all locks except the table-level S and X locks. */ lock_remove_all_on_table(table, FALSE); @@ -2790,10 +2809,11 @@ row_truncate_table_for_mysql( dict_index_t* index; - space = 0; + dict_hdr_get_new_id(NULL, NULL, &space); - if (fil_create_new_single_table_tablespace( - &space, table->name, FALSE, flags, + if (space == ULINT_UNDEFINED + || fil_create_new_single_table_tablespace( + space, table->name, FALSE, flags, FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) { ut_print_timestamp(stderr); fprintf(stderr, @@ -2898,7 +2918,7 @@ next_rec: mem_heap_free(heap); - new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); + dict_hdr_get_new_id(&new_id, NULL, NULL); info = pars_info_create(); @@ -2942,7 +2962,7 @@ next_rec: dict_table_autoinc_lock(table); dict_table_autoinc_initialize(table, 1); dict_table_autoinc_unlock(table); - dict_update_statistics(table); + dict_update_statistics(table, TRUE); trx_commit_for_mysql(trx); @@ -3244,6 +3264,8 @@ check_next_foreign: " IF (SQL % NOTFOUND) THEN\n" " found := 0;\n" " ELSE\n" + " DELETE FROM SYS_STATS\n" + " WHERE INDEX_ID = index_id;\n" " DELETE FROM SYS_FIELDS\n" " WHERE INDEX_ID = index_id;\n" " DELETE FROM SYS_INDEXES\n" |