diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_innobase.cc | 94 | ||||
-rw-r--r-- | sql/ha_innobase.h | 2 |
2 files changed, 77 insertions, 19 deletions
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 00d773fc1f9..13046fc80f2 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -35,20 +35,21 @@ Innobase */ #define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1)) -/* The following must be declared here so that we can handle SAFE_MUTEX */ -pthread_mutex_t innobase_mutex; - #include "ha_innobase.h" +/* We must declare this here because we undef SAFE_MUTEX below */ +pthread_mutex_t innobase_mutex; + /* Store MySQL definition of 'byte': in Linux it is char while Innobase uses unsigned char */ typedef byte mysql_byte; -#define INSIDE_HA_INNOBASE_CC #ifdef SAFE_MUTEX #undef pthread_mutex_t #endif +#define INSIDE_HA_INNOBASE_CC + /* Include necessary Innobase headers */ extern "C" { #include "../innobase/include/univ.i" @@ -97,6 +98,8 @@ ulong innobase_active_counter = 0; char* innobase_home = NULL; +char innodb_dummy_stmt_trx_handle = 'D'; + static HASH innobase_open_tables; static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, @@ -198,12 +201,13 @@ check_trx_exists( thd->transaction.all.innobase_tid = trx; /* The execution of a single SQL statement is denoted by - a 'transaction' handle which is a NULL pointer: Innobase + a 'transaction' handle which is a dummy pointer: Innobase remembers internally where the latest SQL statement started, and if error handling requires rolling back the latest statement, Innobase does a rollback to a savepoint. */ - thd->transaction.stmt.innobase_tid = NULL; + thd->transaction.stmt.innobase_tid = + (void*)&innodb_dummy_stmt_trx_handle; } return(trx); @@ -272,10 +276,14 @@ innobase_parse_data_file_paths_and_sizes(void) size = strtoul(str, &endp, 10); str = endp; - if (*str != 'M') { + + if ((*str != 'M') && (*str != 'G')) { size = size / (1024 * 1024); - } else { + } else if (*str == 'G') { + size = size * 1024; str++; + } else { + str++; } if (size == 0) { @@ -318,10 +326,14 @@ innobase_parse_data_file_paths_and_sizes(void) size = strtoul(str, &endp, 10); str = endp; - if (*str != 'M') { + + if ((*str != 'M') && (*str != 'G')) { size = size / (1024 * 1024); - } else { + } else if (*str == 'G') { + size = size * 1024; str++; + } else { + str++; } srv_data_file_names[i] = path; @@ -419,6 +431,13 @@ innobase_init(void) DBUG_ENTER("innobase_init"); + if (specialflag & SPECIAL_NO_PRIOR) { + srv_set_thread_priorities = FALSE; + } else { + srv_set_thread_priorities = TRUE; + srv_query_thread_priority = QUERY_PRIOR; + } + /* Use current_dir if no paths are set */ current_dir[0]=FN_CURLIB; current_dir[1]=FN_LIBCHAR; @@ -557,8 +576,9 @@ innobase_commit( trx = check_trx_exists(thd); - if (trx_handle) { + if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { trx_commit_for_mysql(trx); + trx_mark_sql_stat_end(trx); } else { trx_mark_sql_stat_end(trx); } @@ -585,9 +605,7 @@ innobase_rollback( /* out: 0 or error number */ THD* thd, /* in: handle to the MySQL thread of the user whose transaction should be rolled back */ - void* trx_handle)/* in: Innobase trx handle or NULL: NULL means - that the current SQL statement should be rolled - back */ + void* trx_handle)/* in: Innobase trx handle or a dummy stmt handle */ { int error = 0; trx_t* trx; @@ -597,10 +615,11 @@ innobase_rollback( trx = check_trx_exists(thd); - if (trx_handle) { + if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { error = trx_rollback_for_mysql(trx); } else { error = trx_rollback_last_sql_stat_for_mysql(trx); + trx_mark_sql_stat_end(trx); } DBUG_RETURN(convert_error_code_to_mysql(error)); @@ -618,7 +637,8 @@ innobase_close_connection( whose transaction should be rolled back */ { if (NULL != thd->transaction.all.innobase_tid) { - + trx_rollback_for_mysql((trx_t*) + (thd->transaction.all.innobase_tid)); trx_free_for_mysql((trx_t*) (thd->transaction.all.innobase_tid)); } @@ -726,6 +746,8 @@ ha_innobase::open( user_thd = NULL; + last_query_id = (ulong)-1; + if (!(share=get_share(name))) DBUG_RETURN(1); @@ -1229,6 +1251,11 @@ ha_innobase::write_row( update_timestamp(record + table->time_stamp - 1); } + if (last_query_id != user_thd->query_id) { + prebuilt->sql_stat_start = TRUE; + last_query_id = user_thd->query_id; + } + if (table->next_number_field && record == table->record[0]) { /* Set the 'in_update_remember_pos' flag to FALSE to make sure all columns are fetched in the select done by @@ -1255,8 +1282,17 @@ ha_innobase::write_row( build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); } + if (user_thd->lex.sql_command == SQLCOM_INSERT + && user_thd->lex.duplicates == DUP_IGNORE) { + prebuilt->trx->ignore_duplicates_in_insert = TRUE; + } else { + prebuilt->trx->ignore_duplicates_in_insert = FALSE; + } + error = row_insert_for_mysql((byte*) record, prebuilt); + prebuilt->trx->ignore_duplicates_in_insert = FALSE; + error = convert_error_code_to_mysql(error); /* Tell Innobase server that there might be work for @@ -1441,6 +1477,11 @@ ha_innobase::update_row( DBUG_ENTER("ha_innobase::update_row"); + if (last_query_id != user_thd->query_id) { + prebuilt->sql_stat_start = TRUE; + last_query_id = user_thd->query_id; + } + if (prebuilt->upd_node) { uvect = prebuilt->upd_node->update; } else { @@ -1485,6 +1526,11 @@ ha_innobase::delete_row( DBUG_ENTER("ha_innobase::delete_row"); + if (last_query_id != user_thd->query_id) { + prebuilt->sql_stat_start = TRUE; + last_query_id = user_thd->query_id; + } + if (!prebuilt->upd_node) { row_get_prebuilt_update_vector(prebuilt); } @@ -1590,6 +1636,11 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); statistic_increment(ha_read_key_count, &LOCK_status); + if (last_query_id != user_thd->query_id) { + prebuilt->sql_stat_start = TRUE; + last_query_id = user_thd->query_id; + } + index = prebuilt->index; /* Note that if the select is used for an update, we always @@ -2622,7 +2673,6 @@ ha_innobase::update_table_comment( return(str); } - /**************************************************************************** Handling the shared INNOBASE_SHARE structure that is needed to provide table locking. @@ -2697,12 +2747,18 @@ ha_innobase::store_lock( { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - if (lock_type == TL_READ_WITH_SHARED_LOCKS) { - /* This is a SELECT ... IN SHARE MODE */ + if (lock_type == TL_READ_WITH_SHARED_LOCKS || + lock_type == TL_READ_NO_INSERT) { + /* This is a SELECT ... IN SHARE MODE, or + we are doing a complex SQL statement like + INSERT INTO ... SELECT ... and the logical logging + requires the use of a locking read */ + prebuilt->select_lock_type = LOCK_S; } else { /* We set possible LOCK_X value in external_lock, not yet here even if this would be SELECT ... FOR UPDATE */ + prebuilt->select_lock_type = LOCK_NONE; } diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index df1bcea3cca..0d83b77fb61 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -41,6 +41,8 @@ class ha_innobase: public handler THD* user_thd; /* the thread handle of the user currently using the handle; this is set in external_lock function */ + ulong last_query_id; /* the latest query id where the + handle was used */ THR_LOCK_DATA lock; INNOBASE_SHARE *share; |