summaryrefslogtreecommitdiff
path: root/storage/innobase/handler
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-12-21 21:24:22 +0100
committerSergei Golubchik <serg@mariadb.org>2015-12-21 21:24:22 +0100
commita2bcee626d4ef2836e38e4932305871390164644 (patch)
treeb41e357427318bad8985078b91bbd2b0360defc8 /storage/innobase/handler
parent1788bfe93a745582d938a608d5959b7d2e6b2f23 (diff)
parent4fdf25afa8188905653a83e08fc387243e584600 (diff)
downloadmariadb-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.cc115
-rw-r--r--storage/innobase/handler/handler0alter.cc127
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++) {