3373 magnus.blaudd@stripped 2011-10-03 [merge]
Merge -r 3470 5.5-cluster->trunk-cluster
modified:
mysql-test/suite/ndb/r/ndb_alter_table_online2.result
mysql-test/suite/ndb/t/ndb_alter_table_online2.test
mysql-test/t/disabled.def
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.h
sql/handler.cc
sql/handler.h
sql/sql_table.cc
3372 Frazer Clement 2011-09-30 [merge]
Merge mysql-5.5-cluster -> mysql-trunk-cluster
Includes NDB$EPOCH_TRANS + Binlog events v1.1
added:
mysql-test/suite/ndb_binlog/r/ndb_binlog_log_transaction_id.result
mysql-test/suite/ndb_binlog/t/ndb_binlog_get_row_extra_data.inc
mysql-test/suite/ndb_binlog/t/ndb_binlog_log_transaction_id-master.opt
mysql-test/suite/ndb_binlog/t/ndb_binlog_log_transaction_id.test
mysql-test/suite/ndb_rpl/r/ndb_rpl_conflict_epoch_trans.result
mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_trans.cnf
mysql-test/suite/ndb_rpl/t/ndb_rpl_conflict_epoch_trans.test
mysql-test/suite/ndb_rpl/t/ndb_trans_conflict_info.inc
mysql-test/suite/ndb_rpl/t/ndb_trans_conflict_info_init.inc
mysql-test/suite/ndb_rpl/t/ndb_trans_conflict_info_stable.inc
mysql-test/suite/rpl/r/rpl_extra_row_data.result
mysql-test/suite/rpl/t/rpl_extra_row_data-master.opt
mysql-test/suite/rpl/t/rpl_extra_row_data-slave.opt
mysql-test/suite/rpl/t/rpl_extra_row_data.test
sql/ndb_conflict_trans.cc
sql/ndb_conflict_trans.h
storage/ndb/include/util/HashMap2.hpp
storage/ndb/include/util/LinkedStack.hpp
storage/ndb/src/common/util/HashMap2.cpp
storage/ndb/src/common/util/LinkedStack.cpp
modified:
mysql-test/suite/ndb/r/ndb_basic.result
sql/binlog.cc
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.h
sql/ha_ndbcluster_binlog.cc
sql/ha_ndbcluster_binlog.h
sql/ha_ndbcluster_glue.h
sql/log_event.cc
sql/log_event.h
sql/ndb_mi.cc
sql/ndb_mi.h
sql/ndb_share.h
sql/rpl_constants.h
sql/rpl_slave.h
sql/sql_class.cc
sql/sql_class.h
storage/ndb/CMakeLists.txt
storage/ndb/include/ndbapi/Ndb.hpp
storage/ndb/include/ndbapi/ndb_cluster_connection.hpp
storage/ndb/src/common/portlib/NdbTCP.cpp
storage/ndb/src/common/util/CMakeLists.txt
storage/ndb/src/ndbapi/Ndb.cpp
storage/ndb/src/ndbapi/Ndbif.cpp
storage/ndb/src/ndbapi/TransporterFacade.cpp
storage/ndb/src/ndbapi/TransporterFacade.hpp
storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
storage/ndb/src/ndbapi/trp_client.cpp
storage/ndb/src/ndbapi/trp_client.hpp
=== modified file 'mysql-test/suite/ndb/r/ndb_alter_table_online2.result'
--- a/mysql-test/suite/ndb/r/ndb_alter_table_online2.result 2011-05-13 11:42:59 +0000
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online2.result 2011-09-09 12:41:37 +0000
@@ -98,6 +98,32 @@ name
't1'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~ test that aborted online alter rollback DDL transaction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+# Connection default
+START TRANSACTION;
+SELECT * FROM t1;
+pk a b c
+1 5000 5000 5000
+# Connection con1
+SET lock_wait_timeout=1;
+ALTER ONLINE TABLE t1 ADD d INT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ALTER ONLINE TABLE t1 ADD d INT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SELECT * FROM t1;
+pk a b c
+1 5000 5000 5000
+COMMIT;
+
+ndb_show_tables completed.....
+
+select name from ndb_show_tables_results where id = @t1_id and name like '%t1%' and type like '%UserTable%';
+name
+'t1'
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ cleanup section
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=== modified file 'mysql-test/suite/ndb/t/ndb_alter_table_online2.test'
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online2.test 2011-05-30 21:13:02 +0000
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online2.test 2011-09-09 12:41:37 +0000
@@ -16,6 +16,8 @@
-- source include/not_windows.inc
# -- source include/have_log_bin.inc
+connection default;
+
--disable_warnings
DROP TABLE IF EXISTS t1;
CREATE DATABASE IF NOT EXISTS mysqlslap;
@@ -178,6 +180,34 @@ ALTER ONLINE TABLE t1 PARTITION BY HASH(
--source ndb_show_tables_result.inc
select name from ndb_show_tables_results where id = @t1_id and name like '%t1%' and type like '%UserTable%';
+
+--echo
+--echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--echo ~ test that aborted online alter rollback DDL transaction
+--echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--echo
+
+connect (con1,localhost,root,,test);
+
+--echo # Connection default
+connection default;
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection con1
+--connection con1
+SET lock_wait_timeout=1;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER ONLINE TABLE t1 ADD d INT;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER ONLINE TABLE t1 ADD d INT;
+SELECT * FROM t1;
+
+connection default;
+COMMIT;
+--source ndb_show_tables_result.inc
+select name from ndb_show_tables_results where id = @t1_id and name like '%t1%' and type like '%UserTable%';
+
--echo
--echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--echo ~ cleanup section
=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def 2011-09-07 10:08:09 +0000
+++ b/mysql-test/t/disabled.def 2011-10-03 07:11:46 +0000
@@ -17,5 +17,3 @@ create-big : Bug#11748731
archive-big : Bug#11817185 2011-03-10 Anitha Disabled since this leads to timeout on Solaris Sparc
log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists
mysql_embedded : Bug#12561297 seems to be fixed in 5.5.16 (I verified that it fails also in tag:mysql-5.5.15)
-innodb_mysql_sync : Merge problems, DEBUG_SYNC wait conditions are not identical, Martin working on it
-kill : Merge problems, DEBUG_SYNC wait conditions are not identical, Martin working on it
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2011-09-30 15:38:44 +0000
+++ b/sql/ha_ndbcluster.cc 2011-10-03 07:11:46 +0000
@@ -16298,7 +16298,7 @@ HA_ALTER_FLAGS supported_alter_operation
int ha_ndbcluster::check_if_supported_alter(TABLE *altered_table,
HA_CREATE_INFO *create_info,
- Alter_info *alter_info,
+ HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags,
uint table_changes)
{
@@ -16984,6 +16984,31 @@ int ha_ndbcluster::alter_table_phase3(TH
alter_info->data= 0;
DBUG_RETURN(0);
}
+
+int ha_ndbcluster::alter_table_abort(THD *thd, TABLE *table,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+{
+ int error= 0;
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
+ NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
+ NDBDICT *dict= alter_data->dictionary;
+ DBUG_ENTER("alter_table_abort");
+ if (dict->endSchemaTrans(NdbDictionary::Dictionary::SchemaTransAbort)
+ == -1)
+ {
+ DBUG_PRINT("info", ("Failed to abort schema transaction"));
+ ERR_PRINT(dict->getNdbError());
+ }
+ /* ndb_share reference schema free */
+ DBUG_PRINT("NDB_SHARE", ("%s binlog schema free use_count: %u",
+ m_share->key, m_share->use_count));
+ delete alter_data;
+ alter_info->data= 0;
+ set_ndb_share_state(m_share, NSS_INITIAL);
+ free_share(&m_share); // Decrease ref_count
+ DBUG_RETURN(error);
+}
#endif
bool set_up_tablespace(st_alter_tablespace *alter_info,
=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h 2011-09-30 15:38:44 +0000
+++ b/sql/ha_ndbcluster.h 2011-10-03 07:11:46 +0000
@@ -517,7 +517,7 @@ static void set_tabname(const char *path
#ifndef NDB_WITHOUT_ONLINE_ALTER
int check_if_supported_alter(TABLE *altered_table,
HA_CREATE_INFO *create_info,
- Alter_info *alter_info,
+ HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags,
uint table_changes);
@@ -537,6 +537,10 @@ static void set_tabname(const char *path
HA_CREATE_INFO *create_info,
HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags);
+
+ int alter_table_abort(THD *thd, TABLE *table,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags);
#endif
private:
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2011-09-28 08:56:16 +0000
+++ b/sql/handler.cc 2011-10-03 07:11:46 +0000
@@ -3757,13 +3757,19 @@ is_index_maintenance_unique (TABLE *tabl
int
handler::check_if_supported_alter(TABLE *altered_table,
HA_CREATE_INFO *create_info,
- Alter_info *alter_info,
+ HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags,
uint table_changes)
{
DBUG_ENTER("check_if_supported_alter");
int result= HA_ALTER_NOT_SUPPORTED;
ulong handler_alter_flags= table->file->alter_table_flags(0);
+ Alter_info *old_alter_info= (Alter_info *) alter_info->data;
+ bool no_pk= ((table->s->primary_key == MAX_KEY) ||
+ alter_flags->is_set(HA_DROP_PK_INDEX));
+ uint candidate_key_count= alter_info->candidate_key_count;
+ bool need_lock_for_indexes= TRUE;
+ enum_alter_table_change_level need_copy_table= old_alter_info->change_level;
HA_ALTER_FLAGS supported_alter_operations;
supported_alter_operations=
supported_alter_operations |
@@ -3785,7 +3791,7 @@ handler::check_if_supported_alter(TABLE
HA_ADD_CONSTRAINT;
HA_ALTER_FLAGS not_supported= ~(supported_alter_operations);
HA_ALTER_FLAGS fast_operations= not_supported & ~(not_fast_operations);
- DBUG_PRINT("info", ("handler_alter_flags: %lu", handler_alter_flags));
+ DBUG_PRINT("info", ("handler_alter_flags: 0x%lx", handler_alter_flags));
#ifndef DBUG_OFF
{
char dbug_string[HA_MAX_ALTER_FLAGS+1];
@@ -3798,17 +3804,12 @@ handler::check_if_supported_alter(TABLE
}
#endif
- /* Bug #49838 DROP INDEX and ADD UNIQUE INDEX for same index may corrupt definition at engine */
- if (is_index_maintenance_unique(table, alter_info))
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
-
/* Check the old alter table flags */
if ((*alter_flags & fast_operations).is_set() &&
table_changes != IS_EQUAL_NO)
{
/* Not adding/dropping index check if supported as fast alter */
- DBUG_PRINT("info", ("alter_info->change_level %u", alter_info->change_level));
- if (alter_info->change_level == ALTER_TABLE_METADATA_ONLY &&
+ if (need_copy_table == ALTER_TABLE_METADATA_ONLY &&
table->file->check_if_incompatible_data(create_info, table_changes)
!= COMPATIBLE_DATA_NO)
DBUG_RETURN(HA_ALTER_SUPPORTED_WAIT_LOCK);
@@ -3819,85 +3820,261 @@ handler::check_if_supported_alter(TABLE
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
else
{
+ /* Adding or dropping index */
+
+ /* Bug #49838 DROP INDEX and ADD UNIQUE INDEX for same index may corrupt definition at engine */
+ if (is_index_maintenance_unique(table, old_alter_info))
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+
+ DBUG_EXECUTE_IF("alter_table_only_metadata_change", {
+ if (need_copy_table != ALTER_TABLE_METADATA_ONLY)
+ DBUG_RETURN(HA_ALTER_ERROR); });
+ DBUG_EXECUTE_IF("alter_table_only_index_change", {
+ if (need_copy_table != ALTER_TABLE_INDEX_CHANGED)
+ DBUG_RETURN(HA_ALTER_ERROR); });
+
+ DBUG_PRINT("info", ("%i: need_copy_table %u", __LINE__, need_copy_table));
+
+ /*
+ 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.
+ */
+ if (need_copy_table == ALTER_TABLE_INDEX_CHANGED)
+ {
+ int pk_changed= 0;
+ ulong alter_flags= 0;
+ ulong needed_inplace_with_read_flags= 0;
+ ulong needed_inplace_flags= 0;
+ KEY *key;
+ uint *idx_p;
+ uint *idx_end_p;
+
+ alter_flags= table->file->alter_table_flags(old_alter_info->flags);
+ DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
+ /* Check dropped indexes. */
+ for (idx_p= alter_info->index_drop_buffer,
+ idx_end_p= idx_p + alter_info->index_drop_count;
+ idx_p < idx_end_p;
+ idx_p++)
+ {
+ key= table->key_info + *idx_p;
+ DBUG_PRINT("info", ("index dropped: '%s'", key->name));
+ if (key->flags & HA_NOSAME)
+ {
+ /*
+ Unique key. Check for "PRIMARY".
+ or if dropping last unique key
+ */
+ if ((uint) (key - table->key_info) == table->s->primary_key)
+ {
+ DBUG_PRINT("info", ("Dropping primary key"));
+ /* Primary key. */
+ 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--;
+ }
+ else
+ {
+ KEY_PART_INFO *part_end= key->key_part + key->key_parts;
+ bool is_candidate_key= true;
+
+ /* Non-primary unique key. */
+ 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
+ NOT NULL and adjust candidate_key_count
+ */
+ for (KEY_PART_INFO *key_part= key->key_part;
+ key_part < part_end;
+ key_part++)
+ is_candidate_key=
+ (is_candidate_key &&
+ (! table->field[key_part->fieldnr-1]->maybe_null()));
+ if (is_candidate_key)
+ candidate_key_count--;
+ }
+ }
+ else
+ {
+ /* Non-unique key. */
+ 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_inplace_with_read_flags &
+ HA_INPLACE_DROP_PK_INDEX_NO_WRITE));
+ /* Check added indexes. */
+ for (idx_p= alter_info->index_add_buffer,
+ idx_end_p= idx_p + alter_info->index_add_count;
+ idx_p < idx_end_p;
+ idx_p++)
+ {
+ key= alter_info->key_info_buffer + *idx_p;
+ DBUG_PRINT("info", ("index added: '%s'", key->name));
+ if (key->flags & HA_NOSAME)
+ {
+ /* Unique key */
+
+ KEY_PART_INFO *part_end= key->key_part + key->key_parts;
+ bool is_candidate_key= true;
+
+ /*
+ Check if all fields in key are declared
+ NOT NULL
+ */
+ for (KEY_PART_INFO *key_part= key->key_part;
+ key_part < part_end;
+ key_part++)
+ is_candidate_key=
+ (is_candidate_key &&
+ (! table->field[key_part->fieldnr]->maybe_null()));
+
+ /*
+ Check for "PRIMARY"
+ or if adding first unique key
+ defined on non-nullable fields
+ */
+
+ if ((!my_strcasecmp(system_charset_info,
+ key->name, primary_key_name)) ||
+ (no_pk && candidate_key_count == 0 && is_candidate_key))
+ {
+ DBUG_PRINT("info", ("Adding primary key"));
+ /* Primary key. */
+ 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_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_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_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_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_inplace_with_read_flags: 0x%lx, needed_inplace_flags: 0x%lx",
+ needed_inplace_with_read_flags, needed_inplace_flags));
+ /*
+ 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_inplace_with_read_flags) ==
+ needed_inplace_with_read_flags)
+ {
+ /* 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_inplace_flags) == needed_inplace_flags)
+ {
+ /* All required in-place flags are present. */
+ need_copy_table= ALTER_TABLE_METADATA_ONLY;
+ }
+ }
+ DBUG_PRINT("info", ("need_copy_table: %u need_lock: %d",
+ need_copy_table, need_lock_for_indexes));
+ }
+
/* Add index */
if ((*alter_flags & HA_ADD_INDEX).is_set() ||
(*alter_flags & HA_ALTER_INDEX).is_set())
{
- if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_READ_WRITE)
+ if (need_copy_table)
+ result= HA_ALTER_NOT_SUPPORTED;
+ else if (need_lock_for_indexes)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
- else if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_WRITE)
- result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
- HA_ALTER_SUPPORTED_WAIT_LOCK
- : HA_ALTER_SUPPORTED_NO_LOCK;
else
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ result= HA_ALTER_SUPPORTED_NO_LOCK;
}
/* Drop index */
if ((*alter_flags & HA_DROP_INDEX).is_set() ||
(*alter_flags & HA_ALTER_INDEX).is_set())
{
- if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_READ_WRITE)
+ if (need_copy_table)
+ result= HA_ALTER_NOT_SUPPORTED;
+ else if (need_lock_for_indexes)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
- else if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_WRITE)
- result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
- HA_ALTER_SUPPORTED_WAIT_LOCK
- : HA_ALTER_SUPPORTED_NO_LOCK;
else
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ result= HA_ALTER_SUPPORTED_NO_LOCK;
}
/* Add unique index */
if ((*alter_flags & HA_ADD_UNIQUE_INDEX).is_set() ||
(*alter_flags & HA_ALTER_UNIQUE_INDEX).is_set())
{
- if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE)
+ if (need_copy_table)
+ result= HA_ALTER_NOT_SUPPORTED;
+ else if (need_lock_for_indexes)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
- else if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE)
- result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
- HA_ALTER_SUPPORTED_WAIT_LOCK
- : HA_ALTER_SUPPORTED_NO_LOCK;
else
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ result= HA_ALTER_SUPPORTED_NO_LOCK;
}
/* Drop unique index */
if ((*alter_flags & HA_DROP_UNIQUE_INDEX).is_set() ||
(*alter_flags & HA_ALTER_UNIQUE_INDEX).is_set())
{
- if (handler_alter_flags & HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE)
+ if (need_copy_table)
+ result= HA_ALTER_NOT_SUPPORTED;
+ else if (need_lock_for_indexes)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
- else if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE)
- result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
- HA_ALTER_SUPPORTED_WAIT_LOCK
- : HA_ALTER_SUPPORTED_NO_LOCK;
else
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ result= HA_ALTER_SUPPORTED_NO_LOCK;
}
/* Add primary key */
if ((*alter_flags & HA_ADD_PK_INDEX).is_set() ||
(*alter_flags & HA_ALTER_PK_INDEX).is_set())
{
- if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE)
+ if (need_copy_table)
+ result= HA_ALTER_NOT_SUPPORTED;
+ else if (need_lock_for_indexes)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
- else if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE)
- result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
- HA_ALTER_SUPPORTED_WAIT_LOCK
- : HA_ALTER_SUPPORTED_NO_LOCK;
else
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ result= HA_ALTER_SUPPORTED_NO_LOCK;
}
/* Drop primary key */
if ((*alter_flags & HA_DROP_PK_INDEX).is_set() ||
(*alter_flags & HA_ALTER_PK_INDEX).is_set())
{
- if (handler_alter_flags & HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE)
+ if (need_copy_table)
+ result= HA_ALTER_NOT_SUPPORTED;
+ else if (need_lock_for_indexes)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
- else if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE)
- result= (result == HA_ALTER_SUPPORTED_WAIT_LOCK)?
- HA_ALTER_SUPPORTED_WAIT_LOCK
- : HA_ALTER_SUPPORTED_NO_LOCK;
else
- DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+ result= HA_ALTER_SUPPORTED_NO_LOCK;
}
}
+
DBUG_RETURN(result);
}
@@ -3919,7 +4096,7 @@ handler::alter_table_phase1(THD *thd,
adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX |
HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
- dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX |
+ dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX | HA_DROP_PK_INDEX |
HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
if ((*alter_flags & adding).is_set())
@@ -3956,6 +4133,7 @@ handler::alter_table_phase1(THD *thd,
table->key_info= key_info;
table->file->print_error(error, MYF(0));
table->key_info= save_key_info;
+ //my_error(error, MYF(0));
DBUG_RETURN(error);
}
/*
@@ -3976,12 +4154,11 @@ handler::alter_table_phase1(THD *thd,
{
if ((error= final_add_index((handler_add_index *)alter_info->data, true)))
{
- print_error(error, MYF(0));
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
}
- DBUG_PRINT("info", ("Renumbering indexes"));
/* The prepare_drop_index() method takes an array of key numbers. */
key_numbers= (uint*) thd->alloc(sizeof(uint) * alter_info->index_drop_count);
keyno_p= key_numbers;
@@ -4016,22 +4193,29 @@ handler::alter_table_phase2(THD *thd,
adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX |
HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
- dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX |
+ dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX | HA_DROP_PK_INDEX |
HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
if ((*alter_flags & dropping).is_set())
{
if ((error= final_drop_index(table)))
{
- print_error(error, MYF(0));
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
}
else if ((*alter_flags & adding).is_set())
{
+ DBUG_EXECUTE_IF("alter_table_rollback_new_index", {
+ error= ER_UNKNOWN_ERROR;
+ table->file->final_add_index((handler_add_index *)alter_info->data,
+ false);
+ my_error(error, MYF(0));
+ DBUG_RETURN(error);
+ });
if ((error= final_add_index((handler_add_index *)alter_info->data, true)))
{
- print_error(error, MYF(0));
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
}
@@ -4048,6 +4232,32 @@ handler::alter_table_phase3(THD *thd, TA
DBUG_ENTER("alter_table_phase3");
DBUG_RETURN(0);
}
+
+int
+handler::alter_table_abort(THD *thd,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags)
+{
+ DBUG_ENTER("alter_table_abort");
+ int error= 0;
+ HA_ALTER_FLAGS adding;
+
+ adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX |
+ HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
+
+ if ((*alter_flags & adding).is_set())
+ {
+ if ((error=
+ table->file->final_add_index((handler_add_index *)alter_info->data,
+ false)))
+ table->file->print_error(error, MYF(0));
+ else
+ table->file->print_error(ER_UNKNOWN_ERROR, MYF(0));
+ DBUG_RETURN(error);
+ }
+ DBUG_RETURN(0);
+}
+
#endif
/**
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2011-09-28 18:53:09 +0000
+++ b/sql/handler.h 2011-10-03 07:11:46 +0000
@@ -1015,6 +1015,7 @@ typedef struct st_ha_alter_information
{
KEY *key_info_buffer;
uint key_count;
+ uint candidate_key_count;
uint index_drop_count;
uint *index_drop_buffer;
uint index_add_count;
@@ -2371,7 +2372,7 @@ public:
*/
virtual int check_if_supported_alter(TABLE *altered_table,
HA_CREATE_INFO *create_info,
- Alter_info *alter_info,
+ HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags,
uint table_changes);
@@ -2436,6 +2437,19 @@ public:
HA_CREATE_INFO *create_info,
HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *alter_flags);
+
+ /**
+ Tell storage engine to abort (rollback) the ongoing online
+ alter table and release any allocated resources (this will be last call).
+
+ @param thd The thread handle
+ @param alter_info Storage place for data used during phase1
+ and phase2 and phase3
+ @param alter_flags Bitmask that shows what has been changed
+ */
+ virtual int alter_table_abort(THD *thd,
+ HA_ALTER_INFO *alter_info,
+ HA_ALTER_FLAGS *alter_flags);
#endif
/**
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2011-09-23 10:44:30 +0000
+++ b/sql/sql_table.cc 2011-10-03 07:11:46 +0000
@@ -5707,6 +5707,9 @@ compare_tables(THD *thd,
DBUG_PRINT("info", ("index added: '%s'", new_key->name));
}
}
+ if (ha_alter_info->index_drop_count || ha_alter_info->index_add_count)
+ alter_info->change_level= ALTER_TABLE_INDEX_CHANGED;
+ ha_alter_info->candidate_key_count= candidate_key_count;
#ifndef DBUG_OFF
{
char dbug_string[HA_MAX_ALTER_FLAGS+1];
@@ -6292,6 +6295,7 @@ int mysql_fast_or_online_alter_table(THD
HA_ALTER_INFO *alter_info,
HA_ALTER_FLAGS *ha_alter_flags,
enum enum_enable_or_disable keys_onoff,
+ bool need_lock_for_indexes,
MDL_request *target_mdl_request)
{
int error= 0;
@@ -6309,13 +6313,15 @@ int mysql_fast_or_online_alter_table(THD
DBUG_ENTER(" mysql_fast_or_online_alter_table");
//VOID(pthread_mutex_lock(&LOCK_open));
- if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
+ if (!table->s->tmp_table && need_lock_for_indexes &&
+ (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)))
{
- error= my_errno;
+ error= -1;
goto err;
}
//VOID(pthread_mutex_unlock(&LOCK_open));
thd_proc_info(thd, "manage keys");
+ DEBUG_SYNC(thd, "alter_table_manage_keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
keys_onoff);
error= trans_commit_stmt(thd);
@@ -6349,6 +6355,24 @@ int mysql_fast_or_online_alter_table(THD
if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
we need to wrap the next call with a DDL lock.
*/
+
+
+ /*
+ Wait for users of the table before continuing with next phase
+ */
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
+ {
+ if ((error= table->file->alter_table_abort(thd,
+ alter_info,
+ ha_alter_flags)))
+ {
+ goto err;
+ }
+
+ error= my_errno;
+ goto err;
+ }
+
if ((error= table->file->alter_table_phase2(thd,
altered_table,
create_info,
@@ -6363,11 +6387,6 @@ int mysql_fast_or_online_alter_table(THD
and will be renamed to the original table name.
*/
//VOID(pthread_mutex_lock(&LOCK_open));
- if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
- {
- error= my_errno;
- goto err;
- }
strcpy(table_name, altered_table->s->table_name.str);
strcpy(db, altered_table->s->db.str);
@@ -7752,7 +7771,8 @@ bool mysql_alter_table(THD *thd,char *ne
{
char dbug_string[HA_MAX_ALTER_FLAGS+1];
ha_alter_flags.print(dbug_string);
- DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags: %s",
+ DBUG_PRINT("info", ("change_level: %u, need_copy_table: %u, table_changes: %u, Real alter_flags: %s",
+ alter_info->change_level,
need_copy_table, table_changes,
(char *) dbug_string));
}
@@ -7795,10 +7815,11 @@ bool mysql_alter_table(THD *thd,char *ne
alter_info->create_list= create_list_orig;
alter_info->alter_list= alter_list_orig;
alter_info->key_list= key_list_orig;
-
+ ha_alter_info.data= alter_info;
+
alter_supported= (table->file->check_if_supported_alter(altered_table,
create_info,
- alter_info,
+ &ha_alter_info,
&ha_alter_flags,
table_changes));
@@ -7809,7 +7830,12 @@ bool mysql_alter_table(THD *thd,char *ne
alter_info->key_list= key_list;
switch (alter_supported) {
case HA_ALTER_SUPPORTED_WAIT_LOCK:
+ DBUG_PRINT("info", ("check_if_supported_alter: HA_ALTER_SUPPORTED_WAIT_LOCK"));
+ need_copy_table= FALSE;
+ need_lock_for_indexes= TRUE;
+ break;
case HA_ALTER_SUPPORTED_NO_LOCK:
+ DBUG_PRINT("info", ("check_if_supported_alter: HA_ALTER_SUPPORTED_NO_LOCK"));
/*
@todo: Currently we always acquire an exclusive name
lock on the table metadata when performing fast or online
@@ -7820,10 +7846,12 @@ bool mysql_alter_table(THD *thd,char *ne
already now.
*/
need_copy_table= FALSE;
- if (alter_info->change_level == ALTER_TABLE_METADATA_ONLY)
- need_lock_for_indexes= FALSE;
+ need_lock_for_indexes= FALSE;
break;
case HA_ALTER_NOT_SUPPORTED:
+ DBUG_PRINT("info", ("check_if_supported_alter: HA_ALTER_NOT_SUPPORTED"));
+ need_copy_table= TRUE;
+ need_lock_for_indexes= FALSE;
if (alter_info->build_method == HA_BUILD_ONLINE)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query());
@@ -7836,6 +7864,7 @@ bool mysql_alter_table(THD *thd,char *ne
need_copy_table= TRUE;
break;
case HA_ALTER_ERROR:
+ DBUG_PRINT("info", ("check_if_supported_alter: HA_ALTER_ERROR"));
default:
#ifdef WITH_PARTITION_STORAGE_ENGINE
altered_table->part_info= NULL;;
@@ -7860,6 +7889,9 @@ bool mysql_alter_table(THD *thd,char *ne
if (!need_copy_table)
{
+ if (alter_info->keys_onoff != LEAVE_AS_IS ||
+ table->file->indexes_are_disabled())
+ need_lock_for_indexes= true;
error= mysql_fast_or_online_alter_table(thd,
table,
altered_table,
@@ -7867,6 +7899,7 @@ bool mysql_alter_table(THD *thd,char *ne
&ha_alter_info,
&ha_alter_flags,
alter_info->keys_onoff,
+ need_lock_for_indexes,
&target_mdl_request);
if (thd->lock)
{
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk-cluster branch (magnus.blaudd:3372 to 3373) | magnus.blaudd | 3 Oct |