diff options
author | heikki@hundin.mysql.fi <> | 2002-07-31 00:47:20 +0300 |
---|---|---|
committer | heikki@hundin.mysql.fi <> | 2002-07-31 00:47:20 +0300 |
commit | bbb8125a2cad4845a61efe0f63906bd0cb64ec20 (patch) | |
tree | c292c07f8ce5669e3036ef6b705c347df3e64c0c /sql | |
parent | c5bdaee9ad98c363d16c97292d14eb0ce2a890b9 (diff) | |
download | mariadb-git-bbb8125a2cad4845a61efe0f63906bd0cb64ec20.tar.gz |
Many files:
Merge InnoDB-3.23.52c; improve AUTO-INC algorithm with SHOW TABLE STATUS; new checksum in log
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_innobase.cc | 223 | ||||
-rw-r--r-- | sql/ha_innobase.h | 1 |
2 files changed, 154 insertions, 70 deletions
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 1bf619855c9..b952e297c85 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -266,10 +266,39 @@ innobase_mysql_print_thd( thd = (THD*) input_thd; + buf += sprintf(buf, "MySQL thread id %lu, query id %lu", + thd->thread_id, thd->query_id); + if (thd->host) { + buf += sprintf(buf, " %.30s", thd->host); + } + + if (thd->ip) { + buf += sprintf(buf, " %.20s", thd->ip); + } + + if (thd->user) { + buf += sprintf(buf, " %.20s", thd->user); + } + + if (thd->proc_info) { + buf += sprintf(buf, " %.50s", thd->proc_info); + } + + if (thd->query) { + buf += sprintf(buf, "\n%.150s", thd->query); + } + + buf += sprintf(buf, "\n"); + +#ifdef notdefined + /* July 30, 2002 + Revert Monty's changes because they seem to make control + characters sometimes appear in the output */ + /* We can't use value of sprintf() as this is not portable */ buf+= my_sprintf(buf, - (buf, "MySQL thread id %lu, query id %lu", - thd->thread_id, thd->query_id)); + (buf, "MySQL thread id %lu", + thd->thread_id)); if (thd->host) { *buf++=' '; @@ -296,10 +325,11 @@ innobase_mysql_print_thd( if (thd->query) { - *buf++=' '; + *buf++='\n'; buf=strnmov(buf, thd->query, 150); } *buf='\n'; +#endif } } @@ -1414,6 +1444,7 @@ ha_innobase::write_row( row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; int error; longlong auto_inc; + longlong dummy; DBUG_ENTER("ha_innobase::write_row"); @@ -1436,7 +1467,31 @@ ha_innobase::write_row( if (table->next_number_field && record == table->record[0]) { /* This is the case where the table has an auto-increment column */ - + + /* Initialize the auto-inc counter if it has not been + initialized yet */ + + if (0 == dict_table_autoinc_peek(prebuilt->table)) { + + /* This call initializes the counter */ + error = innobase_read_and_init_auto_inc(&dummy); + + if (error) { + /* Deadlock or lock wait timeout */ + + goto func_exit; + } + + /* We have to set sql_stat_start to TRUE because + the above call probably has called a select, and + has reset that flag; row_insert_for_mysql has to + know to set the IX intention lock on the table, + something it only does at the start of each + statement */ + + prebuilt->sql_stat_start = TRUE; + } + /* Fetch the value the user possibly has set in the autoincrement field */ @@ -1469,10 +1524,9 @@ ha_innobase::write_row( } if (auto_inc != 0) { - /* This call will calculate the max of the - current value and the value supplied by the user, if - the auto_inc counter is already initialized - for the table */ + /* This call will calculate the max of the current + value and the value supplied by the user and + update the counter accordingly */ /* We have to use the transactional lock mechanism on the auto-inc counter of the table to ensure @@ -1512,46 +1566,18 @@ ha_innobase::write_row( auto_inc = dict_table_autoinc_get(prebuilt->table); srv_conc_exit_innodb(prebuilt->trx); - /* If auto_inc is now != 0 the autoinc counter - was already initialized for the table: we can give - the new value for MySQL to place in the field */ + /* We can give the new value for MySQL to place in + the field */ - if (auto_inc != 0) { - user_thd->next_insert_id = auto_inc; - } + user_thd->next_insert_id = auto_inc; } - - update_auto_increment(); - if (auto_inc == 0) { - /* The autoinc counter for our table was not yet - initialized, initialize it now */ - - auto_inc = table->next_number_field->val_int(); - - srv_conc_enter_innodb(prebuilt->trx); - error = row_lock_table_autoinc_for_mysql(prebuilt); - srv_conc_exit_innodb(prebuilt->trx); + /* This call of a handler.cc function places + user_thd->next_insert_id to the column value, if the column + value was not set by the user */ - if (error != DB_SUCCESS) { - - error = convert_error_code_to_mysql(error, - user_thd); - goto func_exit; - } - - dict_table_autoinc_initialize(prebuilt->table, - auto_inc); - } - - /* We have to set sql_stat_start to TRUE because - update_auto_increment may have called a select, and - has reset that flag; row_insert_for_mysql has to - know to set the IX intention lock on the table, something - it only does at the start of each statement */ - - prebuilt->sql_stat_start = TRUE; - } + update_auto_increment(); + } if (prebuilt->mysql_template == NULL || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) { @@ -3572,37 +3598,53 @@ ha_innobase::store_lock( } /*********************************************************************** -Returns the next auto-increment column value for the table. write_row -normally fetches the value from the cache in the data dictionary. This -function in used by SHOW TABLE STATUS and when the first insert to the table -is done after database startup. */ +This function initializes the auto-inc counter if it has not been +initialized yet. This function does not change the value of the auto-inc +counter if it already has been initialized. In parameter ret returns +the value of the auto-inc counter. */ -longlong -ha_innobase::get_auto_increment() -/*=============================*/ - /* out: the next auto-increment column value */ +int +ha_innobase::innobase_read_and_init_auto_inc( +/*=========================================*/ + /* out: 0 or error code: deadlock or + lock wait timeout */ + longlong* ret) /* out: auto-inc value */ { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - longlong nr; + longlong auto_inc; int error; + ut_a(prebuilt); ut_a(prebuilt->trx == (trx_t*) current_thd->transaction.all.innobase_tid); + ut_a(prebuilt->table); + + auto_inc = dict_table_autoinc_read(prebuilt->table); + + if (auto_inc != 0) { + /* Already initialized */ + *ret = auto_inc; + + return(0); + } - /* Also SHOW TABLE STATUS calls this function. Previously, when we did - always read the max autoinc key value, setting x-locks, users were - surprised that SHOW TABLE STATUS could end up in a deadlock with - ordinary SQL queries. We avoid these deadlocks if the auto-inc - counter for the table has been initialized by fetching the value - from the table struct in dictionary cache. */ + srv_conc_enter_innodb(prebuilt->trx); + error = row_lock_table_autoinc_for_mysql(prebuilt); + srv_conc_exit_innodb(prebuilt->trx); - assert(prebuilt->table); - - nr = dict_table_autoinc_read(prebuilt->table); + if (error != DB_SUCCESS) { + error = convert_error_code_to_mysql(error, user_thd); + + goto func_exit; + } - if (nr != 0) { + /* Check again if someone has initialized the counter meanwhile */ + auto_inc = dict_table_autoinc_read(prebuilt->table); - return(nr + 1); + if (auto_inc != 0) { + *ret = auto_inc; + + return(0); } (void) extra(HA_EXTRA_KEYREAD); @@ -3622,22 +3664,63 @@ ha_innobase::get_auto_increment() prebuilt->hint_no_need_to_fetch_extra_cols = FALSE; - prebuilt->trx->mysql_n_tables_locked += 1; + prebuilt->trx->mysql_n_tables_locked += 1; - error = index_last(table->record[1]); + error = index_last(table->record[1]); if (error) { - nr = 1; + if (error == HA_ERR_END_OF_FILE) { + /* The table was empty, initialize to 1 */ + auto_inc = 1; + + error = 0; + } else { + /* Deadlock or a lock wait timeout */ + auto_inc = -1; + + goto func_exit; + } } else { - nr = (longlong) table->next_number_field-> + /* Initialize to max(col) + 1 */ + auto_inc = (longlong) table->next_number_field-> val_int_offset(table->rec_buff_length) + 1; } + dict_table_autoinc_initialize(prebuilt->table, auto_inc); + +func_exit: (void) extra(HA_EXTRA_NO_KEYREAD); - index_end(); + index_end(); + + *ret = auto_inc; + + return(error); +} + +/*********************************************************************** +This function initializes the auto-inc counter if it has not been +initialized yet. This function does not change the value of the auto-inc +counter if it already has been initialized. Returns the value of the +auto-inc counter. */ + +longlong +ha_innobase::get_auto_increment() +/*=============================*/ + /* out: auto-increment column value, -1 if error + (deadlock or lock wait timeout) */ +{ + longlong nr; + int error; + + error = innobase_read_and_init_auto_inc(&nr); + + if (error) { + + return(-1); + } - return(nr); + return(nr); } #endif /* HAVE_INNOBASE_DB */ diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index 4a9f3a6251b..abb6ade79f7 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -68,6 +68,7 @@ class ha_innobase: public handler int update_thd(THD* thd); int change_active_index(uint keynr); int general_fetch(byte* buf, uint direction, uint match_mode); + int innobase_read_and_init_auto_inc(longlong* ret); /* Init values for the class: */ public: |