summaryrefslogtreecommitdiff
path: root/storage/xtradb/row/row0mysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/row/row0mysql.c')
-rw-r--r--storage/xtradb/row/row0mysql.c134
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"