diff options
| author | Sergei Golubchik <serg@mariadb.org> | 2015-12-21 21:24:22 +0100 |
|---|---|---|
| committer | Sergei Golubchik <serg@mariadb.org> | 2015-12-21 21:24:22 +0100 |
| commit | a2bcee626d4ef2836e38e4932305871390164644 (patch) | |
| tree | b41e357427318bad8985078b91bbd2b0360defc8 /storage/innobase/handler | |
| parent | 1788bfe93a745582d938a608d5959b7d2e6b2f23 (diff) | |
| parent | 4fdf25afa8188905653a83e08fc387243e584600 (diff) | |
| download | mariadb-git-a2bcee626d4ef2836e38e4932305871390164644.tar.gz | |
Merge branch '10.0' into 10.1
Diffstat (limited to 'storage/innobase/handler')
| -rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 115 | ||||
| -rw-r--r-- | storage/innobase/handler/handler0alter.cc | 127 |
2 files changed, 151 insertions, 91 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 587e16a67cb..359805ff95d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -117,6 +117,9 @@ this program; if not, write to the Free Software Foundation, Inc., #include "ha_innodb.h" #include "i_s.h" +#include <string> +#include <sstream> + #include <mysql/plugin.h> #include <mysql/service_wsrep.h> @@ -2283,10 +2286,11 @@ innobase_next_autoinc( if (next_value == 0) { ulonglong next; - if (current > offset) { + if (current >= offset) { next = (current - offset) / step; } else { - next = (offset - current) / step; + next = 0; + block -= step; } ut_a(max_value > next); @@ -13793,8 +13797,9 @@ ha_innobase::update_table_comment( const char* comment)/*!< in: table comment defined by user */ { uint length = (uint) strlen(comment); - char* str; + char* str=0; long flen; + std::string fk_str; /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table @@ -13812,50 +13817,40 @@ ha_innobase::update_table_comment( possible adaptive hash latch to avoid deadlocks of threads */ trx_search_latch_release_if_reserved(prebuilt->trx); - str = NULL; - - /* output the data to a temporary file */ - if (!srv_read_only_mode) { - - mutex_enter(&srv_dict_tmpfile_mutex); +#define SSTR( x ) reinterpret_cast< std::ostringstream & >( \ + ( std::ostringstream() << std::dec << x ) ).str() - rewind(srv_dict_tmpfile); + fk_str.append("InnoDB free: "); + fk_str.append(SSTR(fsp_get_available_space_in_free_extents( + prebuilt->table->space))); - fprintf(srv_dict_tmpfile, "InnoDB free: %llu kB", - fsp_get_available_space_in_free_extents( - prebuilt->table->space)); + fk_str.append(dict_print_info_on_foreign_keys( + FALSE, prebuilt->trx, + prebuilt->table)); - dict_print_info_on_foreign_keys( - FALSE, srv_dict_tmpfile, prebuilt->trx, - prebuilt->table); + flen = fk_str.length(); - flen = ftell(srv_dict_tmpfile); - - if (flen < 0) { - flen = 0; - } else if (length + flen + 3 > 64000) { - flen = 64000 - 3 - length; - } + if (flen < 0) { + flen = 0; + } else if (length + flen + 3 > 64000) { + flen = 64000 - 3 - length; + } - /* allocate buffer for the full string, and - read the contents of the temporary file */ + /* allocate buffer for the full string */ - str = (char*) my_malloc(length + flen + 3, MYF(0)); + str = (char*) my_malloc(length + flen + 3, MYF(0)); - if (str) { - char* pos = str + length; - if (length) { - memcpy(str, comment, length); - *pos++ = ';'; - *pos++ = ' '; - } - rewind(srv_dict_tmpfile); - flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile); - pos[flen] = 0; + if (str) { + char* pos = str + length; + if (length) { + memcpy(str, comment, length); + *pos++ = ';'; + *pos++ = ' '; } - mutex_exit(&srv_dict_tmpfile_mutex); + memcpy(pos, fk_str.c_str(), flen); + pos[flen] = 0; } prebuilt->trx->op_info = (char*)""; @@ -13873,8 +13868,7 @@ char* ha_innobase::get_foreign_key_create_info(void) /*==========================================*/ { - long flen; - char* str = 0; + char* fk_str = 0; ut_a(prebuilt != NULL); @@ -13892,38 +13886,22 @@ ha_innobase::get_foreign_key_create_info(void) trx_search_latch_release_if_reserved(prebuilt->trx); - if (!srv_read_only_mode) { - mutex_enter(&srv_dict_tmpfile_mutex); - rewind(srv_dict_tmpfile); - - /* Output the data to a temporary file */ - dict_print_info_on_foreign_keys( - TRUE, srv_dict_tmpfile, prebuilt->trx, + /* Output the data to a temporary file */ + std::string str = dict_print_info_on_foreign_keys( + TRUE, prebuilt->trx, prebuilt->table); - prebuilt->trx->op_info = (char*)""; - - flen = ftell(srv_dict_tmpfile); - - if (flen < 0) { - flen = 0; - } - - /* Allocate buffer for the string, and - read the contents of the temporary file */ - - str = (char*) my_malloc(flen + 1, MYF(0)); + prebuilt->trx->op_info = (char*)""; - if (str) { - rewind(srv_dict_tmpfile); - flen = (uint) fread(str, 1, flen, srv_dict_tmpfile); - str[flen] = 0; - } + /* Allocate buffer for the string */ + fk_str = (char*) my_malloc(str.length() + 1, MYF(0)); - mutex_exit(&srv_dict_tmpfile_mutex); + if (fk_str) { + memcpy(fk_str, str.c_str(), str.length()); + fk_str[str.length()]='\0'; } - return(str); + return(fk_str); } @@ -15542,10 +15520,7 @@ ha_innobase::get_auto_increment( current = *first_value; - /* If the increment step of the auto increment column - decreases then it is not affecting the immediate - next value in the series. */ - if (prebuilt->autoinc_increment > increment) { + if (prebuilt->autoinc_increment != increment) { WSREP_DEBUG("autoinc decrease: %llu -> %llu\n" "THD: %ld, current: %llu, autoinc: %llu", @@ -15559,7 +15534,7 @@ ha_innobase::get_auto_increment( } current = innobase_next_autoinc( - current, 1, increment, 1, col_max_value); + current, 1, increment, offset, col_max_value); dict_table_autoinc_initialize(prebuilt->table, current); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3ae3e5bfe5e..74f36467f1f 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -163,10 +163,13 @@ my_error_innodb( /* TODO: report the row, as we do for DB_DUPLICATE_KEY */ my_error(ER_INVALID_USE_OF_NULL, MYF(0)); break; + case DB_TABLESPACE_EXISTS: + my_error(ER_TABLESPACE_EXISTS, MYF(0), table); + break; + #ifdef UNIV_DEBUG case DB_SUCCESS: case DB_DUPLICATE_KEY: - case DB_TABLESPACE_EXISTS: case DB_ONLINE_LOG_TOO_BIG: /* These codes should not be passed here. */ ut_error; @@ -5205,6 +5208,61 @@ commit_cache_rebuild( DBUG_VOID_RETURN; } +/** Store the column number of the columns in a list belonging +to indexes which are not being dropped. +@param[in] ctx In-place ALTER TABLE context +@param[out] drop_col_list list which will be set, containing columns + which is part of index being dropped */ +static +void +get_col_list_to_be_dropped( + ha_innobase_inplace_ctx* ctx, + std::set<ulint>& drop_col_list) +{ + for (ulint index_count = 0; index_count < ctx->num_to_drop_index; + index_count++) { + dict_index_t* index = ctx->drop_index[index_count]; + + for (ulint col = 0; col < index->n_user_defined_cols; col++) { + ulint col_no = dict_index_get_nth_col_no(index, col); + drop_col_list.insert(col_no); + } + } +} + +/** For each column, which is part of an index which is not going to be +dropped, it checks if the column number of the column is same as col_no +argument passed. +@param[in] table table object +@param[in] col_no column number of the column which is to be checked +@retval true column exists +@retval false column does not exist. */ +static +bool +check_col_exists_in_indexes( + const dict_table_t* table, + ulint col_no) +{ + for (dict_index_t* index = dict_table_get_first_index(table); index; + index = dict_table_get_next_index(index)) { + + if (index->to_be_dropped) { + continue; + } + + for (ulint col = 0; col < index->n_user_defined_cols; col++) { + + ulint index_col_no = dict_index_get_nth_col_no( + index, col); + if (col_no == index_col_no) { + return(true); + } + } + } + + return(false); +} + /** Commit the changes made during prepare_inplace_alter_table() and inplace_alter_table() inside the data dictionary tables, when not rebuilding the table. @@ -5340,6 +5398,20 @@ commit_cache_norebuild( DBUG_ASSERT(!ctx->need_rebuild()); + std::set<ulint> drop_list; + std::set<ulint>::const_iterator col_it; + + /* Check if the column, part of an index to be dropped is part of any + other index which is not being dropped. If it so, then set the ord_part + of the column to 0. */ + get_col_list_to_be_dropped(ctx, drop_list); + + for(col_it = drop_list.begin(); col_it != drop_list.end(); ++col_it) { + if (!check_col_exists_in_indexes(ctx->new_table, *col_it)) { + ctx->new_table->cols[*col_it].ord_part = 0; + } + } + for (ulint i = 0; i < ctx->num_to_add_index; i++) { dict_index_t* index = ctx->add_index[i]; DBUG_ASSERT(dict_index_get_online_status(index) @@ -5540,6 +5612,7 @@ ha_innobase::commit_inplace_alter_table( Alter_inplace_info* ha_alter_info, bool commit) { + dberr_t error; ha_innobase_inplace_ctx* ctx0 = static_cast<ha_innobase_inplace_ctx*> (ha_alter_info->handler_ctx); @@ -5621,7 +5694,7 @@ ha_innobase::commit_inplace_alter_table( transactions collected during crash recovery could be holding InnoDB locks only, not MySQL locks. */ - dberr_t error = row_merge_lock_table( + error = row_merge_lock_table( prebuilt->trx, ctx->old_table, LOCK_X); if (error != DB_SUCCESS) { @@ -5756,14 +5829,20 @@ ha_innobase::commit_inplace_alter_table( = static_cast<ha_innobase_inplace_ctx*>(*pctx); DBUG_ASSERT(ctx->need_rebuild()); - /* Generate the redo log for the file - operations that will be performed in - commit_cache_rebuild(). */ - fil_mtr_rename_log(ctx->old_table->space, - ctx->old_table->name, - ctx->new_table->space, - ctx->new_table->name, - ctx->tmp_name, &mtr); + /* Check for any possible problems for any + file operations that will be performed in + commit_cache_rebuild(), and if none, generate + the redo log for these operations. */ + error = fil_mtr_rename_log(ctx->old_table, + ctx->new_table, + ctx->tmp_name, &mtr); + if (error != DB_SUCCESS) { + /* Out of memory or a problem will occur + when renaming files. */ + fail = true; + my_error_innodb(error, ctx->old_table->name, + ctx->old_table->flags); + } DBUG_INJECT_CRASH("ib_commit_inplace_crash", crash_inject_count++); } @@ -5776,18 +5855,25 @@ ha_innobase::commit_inplace_alter_table( DBUG_EXECUTE_IF("innodb_alter_commit_crash_before_commit", log_buffer_flush_to_disk(); DBUG_SUICIDE();); - ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(!trx->fts_trx); - ut_ad(trx->insert_undo || trx->update_undo); - /* The following call commits the - mini-transaction, making the data dictionary - transaction committed at mtr.end_lsn. The - transaction becomes 'durable' by the time when - log_buffer_flush_to_disk() returns. In the - logical sense the commit in the file-based - data structures happens here. */ - trx_commit_low(trx, &mtr); + if (fail) { + mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); + mtr_commit(&mtr); + trx_rollback_for_mysql(trx); + } else { + /* The following call commits the + mini-transaction, making the data dictionary + transaction committed at mtr.end_lsn. The + transaction becomes 'durable' by the time when + log_buffer_flush_to_disk() returns. In the + logical sense the commit in the file-based + data structures happens here. */ + ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); + ut_ad(trx->insert_undo || trx->update_undo); + + trx_commit_low(trx, &mtr); + } /* If server crashes here, the dictionary in InnoDB and MySQL will differ. The .ibd files @@ -5809,7 +5895,6 @@ ha_innobase::commit_inplace_alter_table( update the in-memory structures, close some handles, release temporary files, and (unless we rolled back) update persistent statistics. */ - dberr_t error = DB_SUCCESS; for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { |
