summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/innodb_mysql_sync.result65
-rw-r--r--mysql-test/t/innodb_mysql_sync.test133
-rw-r--r--sql/ha_partition.cc26
-rw-r--r--sql/handler.h39
-rw-r--r--sql/sql_table.cc82
-rw-r--r--storage/innobase/handler/ha_innodb.cc11
6 files changed, 285 insertions, 71 deletions
diff --git a/mysql-test/r/innodb_mysql_sync.result b/mysql-test/r/innodb_mysql_sync.result
index d0ba7b0f2e9..58948835f66 100644
--- a/mysql-test/r/innodb_mysql_sync.result
+++ b/mysql-test/r/innodb_mysql_sync.result
@@ -90,3 +90,68 @@ test.t1 optimize status Operation failed
# Connection default
DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
+#
+# Bug#42230 during add index, cannot do queries on storage engines
+# that implement add_index
+#
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t1;
+# Test 1: Secondary index, should not block reads (original test case).
+# Connection default
+CREATE DATABASE db1;
+CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb;
+INSERT INTO db1.t1(value) VALUES (1), (2);
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+# Sending:
+ALTER TABLE db1.t1 ADD INDEX(value);
+# Connection con1
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+USE db1;
+SELECT * FROM t1;
+id value
+1 1
+2 2
+SET DEBUG_SYNC= "now SIGNAL query";
+# Connection default
+# Reaping: ALTER TABLE db1.t1 ADD INDEX(value)
+DROP DATABASE db1;
+# Test 2: Primary index (implicit), should block reads.
+CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+# Sending:
+ALTER TABLE t1 ADD UNIQUE INDEX(a);
+# Connection con1
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+USE test;
+# Sending:
+SELECT * FROM t1;
+# Connection con2
+# Waiting for SELECT to be blocked by the metadata lock on t1
+SET DEBUG_SYNC= "now SIGNAL query";
+# Connection default
+# Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a)
+# Connection con1
+# Reaping: SELECT * FROM t1
+a b
+# Test 3: Primary index (explicit), should block reads.
+# Connection default
+ALTER TABLE t1 DROP INDEX a;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+# Sending:
+ALTER TABLE t1 ADD PRIMARY KEY (a);
+# Connection con1
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+# Sending:
+SELECT * FROM t1;
+# Connection con2
+# Waiting for SELECT to be blocked by the metadata lock on t1
+SET DEBUG_SYNC= "now SIGNAL query";
+# Connection default
+# Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a)
+# Connection con1
+# Reaping: SELECT * FROM t1
+a b
+# Test 4: Secondary unique index, should not block reads.
+# Connection default
+SET DEBUG_SYNC= "RESET";
+DROP TABLE t1;
diff --git a/mysql-test/t/innodb_mysql_sync.test b/mysql-test/t/innodb_mysql_sync.test
index 22c6f3874bc..a8925306c70 100644
--- a/mysql-test/t/innodb_mysql_sync.test
+++ b/mysql-test/t/innodb_mysql_sync.test
@@ -147,6 +147,139 @@ SET DEBUG_SYNC= 'RESET';
disconnect con1;
+--echo #
+--echo # Bug#42230 during add index, cannot do queries on storage engines
+--echo # that implement add_index
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect(con1,localhost,root);
+connect(con2,localhost,root);
+
+--echo # Test 1: Secondary index, should not block reads (original test case).
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb;
+INSERT INTO db1.t1(value) VALUES (1), (2);
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+--echo # Sending:
+--send ALTER TABLE db1.t1 ADD INDEX(value)
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+# Neither of these two statements should be blocked
+USE db1;
+SELECT * FROM t1;
+SET DEBUG_SYNC= "now SIGNAL query";
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER TABLE db1.t1 ADD INDEX(value)
+--reap
+DROP DATABASE db1;
+
+--echo # Test 2: Primary index (implicit), should block reads.
+
+CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+--echo # Sending:
+--send ALTER TABLE t1 ADD UNIQUE INDEX(a)
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+USE test;
+--echo # Sending:
+--send SELECT * FROM t1
+
+--echo # Connection con2
+connection con2;
+--echo # Waiting for SELECT to be blocked by the metadata lock on t1
+let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
+ WHERE state= 'Waiting for table metadata lock'
+ AND info='SELECT * FROM t1';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= "now SIGNAL query";
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a)
+--reap
+
+--echo # Connection con1
+connection con1;
+--echo # Reaping: SELECT * FROM t1
+--reap
+
+--echo # Test 3: Primary index (explicit), should block reads.
+
+--echo # Connection default
+connection default;
+ALTER TABLE t1 DROP INDEX a;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+--echo # Sending:
+--send ALTER TABLE t1 ADD PRIMARY KEY (a)
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+--echo # Sending:
+--send SELECT * FROM t1
+
+--echo # Connection con2
+connection con2;
+--echo # Waiting for SELECT to be blocked by the metadata lock on t1
+let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
+ WHERE state= 'Waiting for table metadata lock'
+ AND info='SELECT * FROM t1';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= "now SIGNAL query";
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a)
+--reap
+
+--echo # Connection con1
+connection con1;
+--echo # Reaping: SELECT * FROM t1
+--reap
+
+--echo # Test 4: Secondary unique index, should not block reads.
+# This requires HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE to be supported
+# by InnoDB. Adding this flag currently introduces a regression so
+# this test is disabled until the regression has been fixed.
+
+--echo # Connection default
+connection default;
+#SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+#--echo # Sending:
+#--send ALTER TABLE t1 ADD UNIQUE (b)
+
+#--echo # Connection con1
+#connection con1;
+#SET DEBUG_SYNC= "now WAIT_FOR manage";
+#SELECT * FROM t1;
+#SET DEBUG_SYNC= "now SIGNAL query";
+
+#--echo # Connection default
+#connection default;
+#--echo # Reaping: ALTER TABLE t1 ADD UNIQUE (b)
+#--reap
+
+disconnect con1;
+disconnect con2;
+SET DEBUG_SYNC= "RESET";
+DROP TABLE t1;
+
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index f717870915f..74f5e116ccf 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,4 +1,4 @@
-/* Copyright 2005-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -6432,28 +6432,28 @@ uint ha_partition::alter_table_flags(uint flags)
already altered, partitions. So both ADD and DROP can only be supported in
pairs.
*/
- flags_to_check= HA_ONLINE_ADD_INDEX_NO_WRITES;
- flags_to_check|= HA_ONLINE_DROP_INDEX_NO_WRITES;
+ flags_to_check= HA_INPLACE_ADD_INDEX_NO_READ_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_INDEX_NO_READ_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
- flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
+ flags_to_check= HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
- flags_to_check|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
+ flags_to_check= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_INDEX;
- flags_to_check|= HA_ONLINE_DROP_INDEX;
+ flags_to_check= HA_INPLACE_ADD_INDEX_NO_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_INDEX_NO_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX;
- flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX;
+ flags_to_check= HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_PK_INDEX;
- flags_to_check|= HA_ONLINE_DROP_PK_INDEX;
+ flags_to_check= HA_INPLACE_ADD_PK_INDEX_NO_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_PK_INDEX_NO_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
DBUG_RETURN(flags_to_return);
diff --git a/sql/handler.h b/sql/handler.h
index 0e03ea17dde..3cd4acee80d 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1,7 +1,7 @@
#ifndef HANDLER_INCLUDED
#define HANDLER_INCLUDED
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -172,28 +172,31 @@
bits in alter_table_flags:
*/
/*
- These bits are set if different kinds of indexes can be created
- off-line without re-create of the table (but with a table lock).
+ These bits are set if different kinds of indexes can be created or dropped
+ in-place without re-creating the table using a temporary table.
+ NO_READ_WRITE indicates that the handler needs concurrent reads and writes
+ of table data to be blocked.
Partitioning needs both ADD and DROP to be supported by its underlying
handlers, due to error handling, see bug#57778.
*/
-#define HA_ONLINE_ADD_INDEX_NO_WRITES (1L << 0) /*add index w/lock*/
-#define HA_ONLINE_DROP_INDEX_NO_WRITES (1L << 1) /*drop index w/lock*/
-#define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES (1L << 2) /*add unique w/lock*/
-#define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES (1L << 3) /*drop uniq. w/lock*/
-#define HA_ONLINE_ADD_PK_INDEX_NO_WRITES (1L << 4) /*add prim. w/lock*/
-#define HA_ONLINE_DROP_PK_INDEX_NO_WRITES (1L << 5) /*drop prim. w/lock*/
+#define HA_INPLACE_ADD_INDEX_NO_READ_WRITE (1L << 0)
+#define HA_INPLACE_DROP_INDEX_NO_READ_WRITE (1L << 1)
+#define HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE (1L << 2)
+#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE (1L << 3)
+#define HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE (1L << 4)
+#define HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE (1L << 5)
/*
- These are set if different kinds of indexes can be created on-line
- (without a table lock). If a handler is capable of one or more of
- these, it should also set the corresponding *_NO_WRITES bit(s).
+ These are set if different kinds of indexes can be created or dropped
+ in-place while still allowing concurrent reads (but not writes) of table
+ data. If a handler is capable of one or more of these, it should also set
+ the corresponding *_NO_READ_WRITE bit(s).
*/
-#define HA_ONLINE_ADD_INDEX (1L << 6) /*add index online*/
-#define HA_ONLINE_DROP_INDEX (1L << 7) /*drop index online*/
-#define HA_ONLINE_ADD_UNIQUE_INDEX (1L << 8) /*add unique online*/
-#define HA_ONLINE_DROP_UNIQUE_INDEX (1L << 9) /*drop uniq. online*/
-#define HA_ONLINE_ADD_PK_INDEX (1L << 10)/*add prim. online*/
-#define HA_ONLINE_DROP_PK_INDEX (1L << 11)/*drop prim. online*/
+#define HA_INPLACE_ADD_INDEX_NO_WRITE (1L << 6)
+#define HA_INPLACE_DROP_INDEX_NO_WRITE (1L << 7)
+#define HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE (1L << 8)
+#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE (1L << 9)
+#define HA_INPLACE_ADD_PK_INDEX_NO_WRITE (1L << 10)
+#define HA_INPLACE_DROP_PK_INDEX_NO_WRITE (1L << 11)
/*
HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
supported at all.
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 064c2b36e17..2855bb0ec4a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -4745,7 +4745,7 @@ err:
@details Checks if any index is being modified (present as both DROP INDEX
and ADD INDEX) in the current ALTER TABLE statement. Needed for disabling
- online ALTER TABLE.
+ in-place ALTER TABLE.
@param table The table being altered
@param alter_info The ALTER TABLE structure
@@ -4861,7 +4861,7 @@ mysql_compare_tables(TABLE *table,
like to keep mysql_compare_tables() idempotent (not altering any
of the arguments) we create a copy of alter_info here and
pass it to mysql_prepare_create_table, then use the result
- to evaluate possibility of fast ALTER TABLE, and then
+ to evaluate possibility of in-place ALTER TABLE, and then
destroy the copy.
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
@@ -4902,9 +4902,9 @@ mysql_compare_tables(TABLE *table,
There was a bug prior to mysql-4.0.25. Number of null fields was
calculated incorrectly. As a result frm and data files gets out of
- sync after fast alter table. There is no way to determine by which
+ sync after in-place alter table. There is no way to determine by which
mysql version (in 4.0 and 4.1 branches) table was created, thus we
- disable fast alter table for all tables created by mysql versions
+ disable in-place alter table for all tables created by mysql versions
prior to 5.0 branch.
See BUG#6236.
*/
@@ -4927,7 +4927,7 @@ mysql_compare_tables(TABLE *table,
}
/*
- Use transformed info to evaluate possibility of fast ALTER TABLE
+ Use transformed info to evaluate possibility of in-place ALTER TABLE
but use the preserved field to persist modifications.
*/
new_field_it.init(alter_info->create_list);
@@ -5207,7 +5207,7 @@ blob_length_by_type(enum_field_types type)
semantic checks.
This function is invoked when we know that we're going to
- perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
+ perform ALTER TABLE via a temporary table -- i.e. in-place ALTER TABLE
is not possible, perhaps because the ALTER statement contains
instructions that require change in table data, not only in
table definition or indexes.
@@ -6102,7 +6102,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/*
- If there are index changes only, try to do them online. "Index
+ If there are index changes only, try to do them in-place. "Index
changes only" means also that the handler for the table does not
change. The table is open and locked. The handler can be accessed.
*/
@@ -6110,8 +6110,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
int pk_changed= 0;
ulong alter_flags= 0;
- ulong needed_online_flags= 0;
- ulong needed_fast_flags= 0;
+ ulong needed_inplace_with_read_flags= 0;
+ ulong needed_inplace_flags= 0;
KEY *key;
uint *idx_p;
uint *idx_end_p;
@@ -6135,8 +6135,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
DBUG_PRINT("info", ("Dropping primary key"));
/* Primary key. */
- needed_online_flags|= HA_ONLINE_DROP_PK_INDEX;
- needed_fast_flags|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_DROP_PK_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE;
pk_changed++;
candidate_key_count--;
}
@@ -6146,8 +6146,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
bool is_candidate_key= true;
/* Non-primary unique key. */
- needed_online_flags|= HA_ONLINE_DROP_UNIQUE_INDEX;
- needed_fast_flags|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|=
+ HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE;
/*
Check if all fields in key are declared
@@ -6166,12 +6167,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
else
{
/* Non-unique key. */
- needed_online_flags|= HA_ONLINE_DROP_INDEX;
- needed_fast_flags|= HA_ONLINE_DROP_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_DROP_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_DROP_INDEX_NO_READ_WRITE;
}
}
no_pk= ((table->s->primary_key == MAX_KEY) ||
- (needed_online_flags & HA_ONLINE_DROP_PK_INDEX));
+ (needed_inplace_with_read_flags &
+ HA_INPLACE_DROP_PK_INDEX_NO_WRITE));
/* Check added indexes. */
for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
idx_p < idx_end_p;
@@ -6209,57 +6211,59 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
DBUG_PRINT("info", ("Adding primary key"));
/* Primary key. */
- needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_PK_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE;
pk_changed++;
no_pk= false;
}
else
{
/* Non-primary unique key. */
- needed_online_flags|= HA_ONLINE_ADD_UNIQUE_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE;
}
}
else
{
/* Non-unique key. */
- needed_online_flags|= HA_ONLINE_ADD_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_INDEX_NO_READ_WRITE;
}
}
- if ((candidate_key_count > 0) &&
- (needed_online_flags & HA_ONLINE_DROP_PK_INDEX))
+ if ((candidate_key_count > 0) &&
+ (needed_inplace_with_read_flags & HA_INPLACE_DROP_PK_INDEX_NO_WRITE))
{
/*
Dropped primary key when there is some other unique
not null key that should be converted to primary key
*/
- needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_PK_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE;
pk_changed= 2;
}
- DBUG_PRINT("info", ("needed_online_flags: 0x%lx, needed_fast_flags: 0x%lx",
- needed_online_flags, needed_fast_flags));
+ DBUG_PRINT("info",
+ ("needed_inplace_with_read_flags: 0x%lx, needed_inplace_flags: 0x%lx",
+ needed_inplace_with_read_flags, needed_inplace_flags));
/*
- Online or fast add/drop index is possible only if
+ In-place add/drop index is possible only if
the primary key is not added and dropped in the same statement.
Otherwise we have to recreate the table.
need_copy_table is no-zero at this place.
*/
if ( pk_changed < 2 )
{
- if ((alter_flags & needed_online_flags) == needed_online_flags)
+ if ((alter_flags & needed_inplace_with_read_flags) ==
+ needed_inplace_with_read_flags)
{
- /* All required online flags are present. */
+ /* All required in-place flags to allow concurrent reads are present. */
need_copy_table= ALTER_TABLE_METADATA_ONLY;
need_lock_for_indexes= FALSE;
}
- else if ((alter_flags & needed_fast_flags) == needed_fast_flags)
+ else if ((alter_flags & needed_inplace_flags) == needed_inplace_flags)
{
- /* All required fast flags are present. */
+ /* All required in-place flags are present. */
need_copy_table= ALTER_TABLE_METADATA_ONLY;
}
}
@@ -6413,10 +6417,18 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
else
{
- if (!table->s->tmp_table &&
+ /*
+ Ensure that we will upgrade the metadata lock if
+ handler::enable/disable_indexes() will be called.
+ */
+ if (alter_info->keys_onoff != LEAVE_AS_IS ||
+ table->file->indexes_are_disabled())
+ need_lock_for_indexes= true;
+ if (!table->s->tmp_table && need_lock_for_indexes &&
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto err_new_table_cleanup;
thd_proc_info(thd, "manage keys");
+ DEBUG_SYNC(thd, "alter_table_manage_keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
alter_info->keys_onoff);
error= trans_commit_stmt(thd);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index e35eabcaea6..191dd53d520 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -2574,11 +2574,12 @@ innobase_alter_table_flags(
/*=======================*/
uint flags)
{
- return(HA_ONLINE_ADD_INDEX_NO_WRITES
- | HA_ONLINE_DROP_INDEX_NO_WRITES
- | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES
- | HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES
- | HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
+ return(HA_INPLACE_ADD_INDEX_NO_READ_WRITE
+ | HA_INPLACE_ADD_INDEX_NO_WRITE
+ | HA_INPLACE_DROP_INDEX_NO_READ_WRITE
+ | HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE
+ | HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE
+ | HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);
}
/*****************************************************************//**