diff options
author | unknown <monty@hundin.mysql.fi> | 2001-11-04 16:14:09 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2001-11-04 16:14:09 +0200 |
commit | 0d1ba873aa11ea581ebbda9f450027329f2e1a3b (patch) | |
tree | 689c9d0271e23431f1ab0ac09e1af4d68a58ca76 /sql/ha_innobase.cc | |
parent | 9f90ff3f12f1fc2bcb70cde74dbd6f27e33e230c (diff) | |
parent | 0176dacd54b7eb62ebc4a81909b189517aee2cb4 (diff) | |
download | mariadb-git-0d1ba873aa11ea581ebbda9f450027329f2e1a3b.tar.gz |
merge with 3.23.44
BitKeeper/etc/ignore:
auto-union
BitKeeper/etc/logging_ok:
auto-union
Docs/manual.texi:
Auto merged
include/my_base.h:
Auto merged
mysql-test/t/func_time.test:
Auto merged
mysql-test/t/join.test:
Auto merged
mysql-test/t/rpl000012.test:
Auto merged
BUILD/FINISH.sh:
Auto merged
BitKeeper/deleted/.del-db_ext.h~a1e210bbd0de0a48:
Auto merged
BitKeeper/deleted/.del-mutex_ext.h~f20f47ddc346598b:
Auto merged
BitKeeper/deleted/.del-violite.c~984c09cffe14a11b:
Auto merged
BitKeeper/deleted/.del-violite.c~d7b85be615595ace:
Auto merged
Build-tools/Do-all-build-steps:
Auto merged
client/client_priv.h:
Auto merged
client/mysqladmin.c:
Auto merged
innobase/include/srv0srv.h:
Auto merged
innobase/include/univ.i:
Auto merged
innobase/log/log0log.c:
Auto merged
innobase/srv/srv0srv.c:
Auto merged
innobase/srv/srv0start.c:
Auto merged
isam/pack_isam.c:
Auto merged
libmysql_r/Makefile.am:
Auto merged
myisam/myisamchk.c:
Auto merged
mysql-test/t/having.test:
Auto merged
mysql-test/t/rpl000015-slave.sh:
Auto merged
mysql-test/t/rpl000016-slave.sh:
Auto merged
mysys/mf_cache.c:
Auto merged
mysys/mf_casecnv.c:
Auto merged
mysys/mf_tempfile.c:
Auto merged
readline/vi_mode.c:
Auto merged
strings/strto.c:
Auto merged
sql/field.cc:
Auto merged
sql/field.h:
Auto merged
sql/ha_berkeley.cc:
Auto merged
sql/ha_myisammrg.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/item.h:
Auto merged
sql/log_event.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/time.cc:
Auto merged
BUILD/SETUP.sh:
Use -mcpu as default (safe for all x86 cpu's)
client/mysqldump.c:
Merge from 3.23.44
configure.in:
Update version number
extra/resolveip.c:
Portability fix
Diffstat (limited to 'sql/ha_innobase.cc')
-rw-r--r-- | sql/ha_innobase.cc | 259 |
1 files changed, 198 insertions, 61 deletions
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 7e11fbe46d1..dd72bb15473 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -79,13 +79,14 @@ ulong innobase_cache_size = 0; long innobase_mirrored_log_groups, innobase_log_files_in_group, innobase_log_file_size, innobase_log_buffer_size, innobase_buffer_pool_size, innobase_additional_mem_pool_size, - innobase_file_io_threads, innobase_lock_wait_timeout; + innobase_file_io_threads, innobase_lock_wait_timeout, + innobase_thread_concurrency, innobase_force_recovery; char *innobase_data_home_dir; char *innobase_log_group_home_dir, *innobase_log_arch_dir; char *innobase_unix_file_flush_method; bool innobase_flush_log_at_trx_commit, innobase_log_archive, - innobase_use_native_aio; + innobase_use_native_aio, innobase_fast_shutdown; /* Set default InnoDB size to 64M, to let users use InnoDB without having @@ -165,19 +166,19 @@ convert_error_code_to_mysql( } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) { - return(1000001); + return(HA_ERR_LOCK_WAIT_TIMEOUT); } else if (error == (int) DB_NO_REFERENCED_ROW) { - return(1000010); + return(HA_ERR_NO_REFERENCED_ROW); } else if (error == (int) DB_ROW_IS_REFERENCED) { - return(1000011); + return(HA_ERR_ROW_IS_REFERENCED); } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) { - return(1000012); + return(HA_ERR_CANNOT_ADD_FOREIGN); } else if (error == (int) DB_OUT_OF_FILE_SPACE) { @@ -354,12 +355,6 @@ innobase_parse_data_file_paths_and_sizes(void) str++; } - if (size >= 4096) { - fprintf(stderr, - "InnoDB: error: data file size must not be >= 4096M\n"); - return(FALSE); - } - if (strlen(str) >= 6 && *str == 'n' && *(str + 1) == 'e' @@ -566,8 +561,10 @@ innobase_init(void) srv_query_thread_priority = QUERY_PRIOR; } - /* Set InnoDB initialization parameters according to the values - read from MySQL .cnf file */ + /* + Set InnoDB initialization parameters according to the values + read from MySQL .cnf file + */ // Make a copy of innobase_data_file_path to not modify the original internal_innobase_data_file_path=my_strdup(innobase_data_file_path, @@ -604,7 +601,7 @@ innobase_init(void) srv_log_archive_on = (ulint) innobase_log_archive; srv_log_buffer_size = (ulint) innobase_log_buffer_size; - srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit; + srv_flush_log_at_trx_commit = (ibool) innobase_flush_log_at_trx_commit; srv_use_native_aio = 0; @@ -614,6 +611,10 @@ innobase_init(void) srv_n_file_io_threads = (ulint) innobase_file_io_threads; srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout; + srv_thread_concurrency = (ulint) innobase_thread_concurrency; + srv_force_recovery = (ulint) innobase_force_recovery; + + srv_fast_shutdown = (ibool) innobase_fast_shutdown; srv_print_verbose_log = mysql_embedded ? 0 : 1; if (strcmp(default_charset_info->name, "latin1") == 0) { @@ -713,12 +714,15 @@ innobase_commit( trx = check_trx_exists(thd); if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { + srv_conc_enter_innodb(trx); + trx_commit_for_mysql(trx); - trx_mark_sql_stat_end_do_not_start_new(trx); - } else { - trx_mark_sql_stat_end(trx); + + srv_conc_exit_innodb(); } + trx_mark_sql_stat_end(trx); + #ifndef DBUG_OFF if (error) { DBUG_PRINT("error", ("error: %d", error)); @@ -751,14 +755,18 @@ innobase_rollback( trx = check_trx_exists(thd); + srv_conc_enter_innodb(trx); + if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { error = trx_rollback_for_mysql(trx); - trx_mark_sql_stat_end_do_not_start_new(trx); } else { error = trx_rollback_last_sql_stat_for_mysql(trx); - trx_mark_sql_stat_end(trx); } + srv_conc_exit_innodb(); + + trx_mark_sql_stat_end(trx); + DBUG_RETURN(convert_error_code_to_mysql(error)); } @@ -908,10 +916,11 @@ ha_innobase::open( if (NULL == (ib_table = dict_table_get(norm_name, NULL))) { fprintf(stderr, -"InnoDB: Cannot find table %s from the internal data dictionary\n" +"InnoDB: Error: cannot find table %s from the internal data dictionary\n" "InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n" "InnoDB: have deleted and recreated InnoDB data files but have forgotten\n" -"InnoDB: to delete the corresponding .frm files of InnoDB tables?\n", +"InnoDB: to delete the corresponding .frm files of InnoDB tables, or you\n" +"InnoDB: have moved .frm files to another database?\n", norm_name); free_share(share); @@ -956,7 +965,9 @@ ha_innobase::open( dbug_assert(key_used_on_scan == MAX_KEY); } - /* Init table lock structure */ + auto_inc_counter_for_this_stat = 0; + + /* Init table lock structure */ thr_lock_data_init(&share->lock,&lock,(void*) 0); info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); @@ -1253,14 +1264,20 @@ build_template( Field* field; ulint n_fields; ulint n_requested_fields = 0; + ibool fetch_all_in_key = FALSE; ulint i; clust_index = dict_table_get_first_index_noninline(prebuilt->table); if (!prebuilt->in_update_remember_pos) { - /* We are building a temporary table: fetch all columns */ - - templ_type = ROW_MYSQL_WHOLE_ROW; + if (prebuilt->read_just_key) { + fetch_all_in_key = TRUE; + } else { + /* We are building a temporary table: fetch all + columns */ + + templ_type = ROW_MYSQL_WHOLE_ROW; + } } if (prebuilt->select_lock_type == LOCK_X) { @@ -1270,7 +1287,6 @@ build_template( templ_type = ROW_MYSQL_WHOLE_ROW; } - if (templ_type == ROW_MYSQL_REC_FIELDS) { if (prebuilt->select_lock_type != LOCK_NONE) { @@ -1310,6 +1326,9 @@ build_template( field = table->field[i]; if (templ_type == ROW_MYSQL_REC_FIELDS + && !(fetch_all_in_key && + ULINT_UNDEFINED != dict_index_get_nth_col_pos( + index, i)) && thd->query_id != field->query_id && thd->query_id != (field->query_id ^ MAX_ULONG_BIT) && thd->query_id != @@ -1408,9 +1427,6 @@ ha_innobase::write_row( } 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 - update_auto_increment */ /* Fetch the value the user possibly has set in the autoincrement field */ @@ -1420,12 +1436,29 @@ ha_innobase::write_row( /* In replication and also otherwise the auto-inc column can be set with SET INSERT_ID. Then we must look at user_thd->next_insert_id. If it is nonzero and the user - has not supplied a value, we must use it. */ + has not supplied a value, we must use it, and use values + incremented by 1 in all subsequent inserts within the + same SQL statement! */ if (auto_inc == 0 && user_thd->next_insert_id != 0) { auto_inc = user_thd->next_insert_id; + auto_inc_counter_for_this_stat = auto_inc; } + if (auto_inc == 0 && auto_inc_counter_for_this_stat) { + /* The user set the auto-inc counter for + this SQL statement with SET INSERT_ID. We must + assign sequential values from the counter. */ + + auto_inc_counter_for_this_stat++; + + auto_inc = auto_inc_counter_for_this_stat; + + /* We give MySQL a new value to place in the + auto-inc column */ + user_thd->next_insert_id = auto_inc; + } + if (auto_inc != 0) { /* This call will calculate the max of the current value and the value supplied by the user, if @@ -1449,11 +1482,14 @@ ha_innobase::write_row( dict_table_autoinc_update(prebuilt->table, auto_inc); } else { + srv_conc_enter_innodb(prebuilt->trx); + if (!prebuilt->trx->auto_inc_lock) { error = row_lock_table_autoinc_for_mysql( prebuilt); if (error != DB_SUCCESS) { + srv_conc_exit_innodb(); error = convert_error_code_to_mysql( error); @@ -1462,6 +1498,7 @@ ha_innobase::write_row( } auto_inc = dict_table_autoinc_get(prebuilt->table); + srv_conc_exit_innodb(); /* If auto_inc is now != 0 the autoinc counter was already initialized for the table: we can give @@ -1472,6 +1509,10 @@ ha_innobase::write_row( } } + /* Set the 'in_update_remember_pos' flag to FALSE to + make sure all columns are fetched in the select done by + update_auto_increment */ + prebuilt->in_update_remember_pos = FALSE; update_auto_increment(); @@ -1482,6 +1523,14 @@ ha_innobase::write_row( auto_inc = table->next_number_field->val_int(); + error = row_lock_table_autoinc_for_mysql(prebuilt); + + if (error != DB_SUCCESS) { + + error = convert_error_code_to_mysql(error); + goto func_exit; + } + dict_table_autoinc_initialize(prebuilt->table, auto_inc); } @@ -1510,8 +1559,12 @@ ha_innobase::write_row( prebuilt->trx->ignore_duplicates_in_insert = FALSE; } + srv_conc_enter_innodb(prebuilt->trx); + error = row_insert_for_mysql((byte*) record, prebuilt); + srv_conc_exit_innodb(); + prebuilt->trx->ignore_duplicates_in_insert = FALSE; error = convert_error_code_to_mysql(error); @@ -1725,8 +1778,12 @@ ha_innobase::update_row( assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); } + srv_conc_enter_innodb(prebuilt->trx); + error = row_update_for_mysql((byte*) old_row, prebuilt); + srv_conc_exit_innodb(); + error = convert_error_code_to_mysql(error); /* Tell InnoDB server that there might be work for @@ -1765,8 +1822,12 @@ ha_innobase::delete_row( prebuilt->upd_node->is_delete = TRUE; prebuilt->in_update_remember_pos = TRUE; + srv_conc_enter_innodb(prebuilt->trx); + error = row_update_for_mysql((byte*) record, prebuilt); + srv_conc_exit_innodb(); + error = convert_error_code_to_mysql(error); /* Tell the InnoDB server that there might be work for @@ -1789,7 +1850,7 @@ ha_innobase::index_init( int error = 0; DBUG_ENTER("index_init"); - change_active_index(keynr); + error = change_active_index(keynr); DBUG_RETURN(error); } @@ -1905,8 +1966,12 @@ ha_innobase::index_read( last_match_mode = match_mode; + srv_conc_enter_innodb(prebuilt->trx); + ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0); + srv_conc_exit_innodb(); + if (ret == DB_SUCCESS) { error = 0; table->status = 0; @@ -1956,11 +2021,20 @@ ha_innobase::change_active_index( prebuilt->table); } + if (!prebuilt->index) { + fprintf(stderr, + "InnoDB: Could not find key n:o %u with name %s from dict cache\n" + "InnoDB: for table %s\n", keynr, key->name, prebuilt->table->name); + + return(1); + } + + assert(prebuilt->search_tuple); + dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields); dict_index_copy_types(prebuilt->search_tuple, prebuilt->index, prebuilt->index->n_fields); - assert(prebuilt->index); /* Maybe MySQL changes the active index for a handle also during some queries, we do not know: then it is safest to build @@ -1989,7 +2063,10 @@ ha_innobase::index_read_idx( uint key_len, /* in: key value length */ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */ { - change_active_index(keynr); + if (change_active_index(keynr)) { + + return(1); + } return(index_read(buf, key, key_len, find_flag)); } @@ -2015,8 +2092,11 @@ ha_innobase::general_fetch( DBUG_ENTER("general_fetch"); - ret = row_search_for_mysql((byte*)buf, 0, prebuilt, - match_mode, direction); + srv_conc_enter_innodb(prebuilt->trx); + + ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode, + direction); + srv_conc_exit_innodb(); if (ret == DB_SUCCESS) { error = 0; @@ -2148,17 +2228,19 @@ ha_innobase::rnd_init( /* out: 0 or error number */ bool scan) /* in: ???????? */ { + int err; + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; if (prebuilt->clust_index_was_generated) { - change_active_index(MAX_KEY); + err = change_active_index(MAX_KEY); } else { - change_active_index(primary_key); + err = change_active_index(primary_key); } start_of_scan = 1; - return(0); + return(err); } /********************************************************************* @@ -2226,11 +2308,15 @@ ha_innobase::rnd_pos( row reference is the row id, not any key value that MySQL knows */ - change_active_index(MAX_KEY); + error = change_active_index(MAX_KEY); } else { - change_active_index(primary_key); + error = change_active_index(primary_key); } + if (error) { + DBUG_RETURN(error); + } + error = index_read(buf, pos, ref_stored_len, HA_READ_KEY_EXACT); change_active_index(keynr); @@ -2285,11 +2371,21 @@ ha_innobase::extra( row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; switch (operation) { + case HA_EXTRA_RESET: + case HA_EXTRA_RESET_STATE: + prebuilt->read_just_key = 0; + break; + case HA_EXTRA_NO_KEYREAD: + prebuilt->read_just_key = 0; + break; case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE: - prebuilt->in_update_remember_pos = FALSE; - break; - default: /* Do nothing */ - ; + prebuilt->in_update_remember_pos = FALSE; + break; + case HA_EXTRA_KEYREAD: + prebuilt->read_just_key = 1; + break; + default:/* Do nothing */ + ; } return(0); @@ -2327,6 +2423,8 @@ ha_innobase::external_lock( prebuilt->sql_stat_start = TRUE; prebuilt->in_update_remember_pos = TRUE; + prebuilt->read_just_key = 0; + if (lock_type == F_WRLCK) { /* If this is a SELECT, then it is in UPDATE TABLE ... @@ -2338,6 +2436,7 @@ ha_innobase::external_lock( if (trx->n_mysql_tables_in_use == 0) { trx_mark_sql_stat_end(trx); } + thd->transaction.all.innodb_active_trans = 1; trx->n_mysql_tables_in_use++; @@ -2347,6 +2446,7 @@ ha_innobase::external_lock( } } else { trx->n_mysql_tables_in_use--; + auto_inc_counter_for_this_stat = 0; if (trx->n_mysql_tables_in_use == 0) { @@ -2363,11 +2463,14 @@ ha_innobase::external_lock( some table in this SQL statement, we release it now */ + srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); + srv_conc_exit_innodb(); } if (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) { + innobase_commit(thd, trx); } } @@ -2636,6 +2739,12 @@ ha_innobase::create( trx_commit_for_mysql(trx); + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ + + log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + innobase_table = dict_table_get(norm_name, NULL); assert(innobase_table); @@ -2685,6 +2794,12 @@ ha_innobase::delete_table( error = row_drop_table_for_mysql(norm_name, trx, FALSE); + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ + + log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + /* Tell the InnoDB server that there might be work for utility threads: */ @@ -2732,6 +2847,12 @@ innobase_drop_database( error = row_drop_database_for_mysql(namebuf, trx); + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ + + log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + /* Tell the InnoDB server that there might be work for utility threads: */ @@ -2778,6 +2899,12 @@ ha_innobase::rename_table( error = row_rename_table_for_mysql(norm_from, norm_to, trx); + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ + + log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP); + /* Tell the InnoDB server that there might be work for utility threads: */ @@ -3062,31 +3189,41 @@ ha_innobase::check( } /***************************************************************** -Adds information about free space in the InnoDB tablespace to a -table comment which is printed out when a user calls SHOW TABLE STATUS. */ +Adds information about free space in the InnoDB tablespace to a table comment +which is printed out when a user calls SHOW TABLE STATUS. Adds also info on +foreign keys. */ char* ha_innobase::update_table_comment( /*==============================*/ - const char* comment) + /* out: table comment + InnoDB free space + + info on foreign keys */ + const char* comment)/* in: table comment defined by user */ { - uint length=strlen(comment); + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + uint length = strlen(comment); + char* str = my_malloc(length + 200, MYF(0)); + char* pos; - char *str=my_malloc(length + 100,MYF(0)), *pos; + if (!str) { + return((char*)comment); + } - if (!str) - return (char*)comment; + pos = str; + if (length) { + pos=strmov(str, comment); + *pos++=';'; + *pos++=' '; + } - pos=str; - if (length) - { - pos=strmov(str,comment); - *pos++=';'; - *pos++=' '; - } - sprintf(pos, "InnoDB free: %lu kB", (ulong) innobase_get_free_space()); + pos += sprintf(pos, "InnoDB free: %lu kB", + (ulong) innobase_get_free_space()); - return(str); + /* We assume 150 bytes of space to print info */ + + dict_print_info_on_foreign_keys(pos, 150, prebuilt->table); + + return(str); } /**************************************************************************** |