diff --git a/mysql-test/r/ndb_binlog_discover.result b/mysql-test/r/ndb_binlog_discover.result new file mode 100644 index 00000000000..2a1bf6efa84 --- /dev/null +++ b/mysql-test/r/ndb_binlog_discover.result @@ -0,0 +1,13 @@ +drop table if exists t1; +create table t1 (a int key) engine=ndb; +reset master; +insert into t1 values(1); +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Table_map # # table_id: # (cluster.apply_status) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +drop table t1; diff --git a/mysql-test/r/ndb_dd_basic.result b/mysql-test/r/ndb_dd_basic.result index 8b16bce830c..d5ac5071a8e 100644 --- a/mysql-test/r/ndb_dd_basic.result +++ b/mysql-test/r/ndb_dd_basic.result @@ -3,11 +3,32 @@ CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' INITIAL_SIZE 16M UNDO_BUFFER_SIZE = 1M -ENGINE=NDB; +ENGINE=MYISAM; +Warnings: +Error 1539 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +ALTER LOGFILE GROUP lg1 +ADD UNDOFILE 'undofile02.dat' +INITIAL_SIZE = 4M +ENGINE=XYZ; +Warnings: +Error 1266 Using storage engine MyISAM for table 'lg1' +Error 1539 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +CREATE TABLESPACE ts1 +ADD DATAFILE 'datafile.dat' +USE LOGFILE GROUP lg1 +INITIAL_SIZE 12M; +Warnings: +Error 1539 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +set storage_engine=ndb; +CREATE LOGFILE GROUP lg1 +ADD UNDOFILE 'undofile.dat' +INITIAL_SIZE 16M +UNDO_BUFFER_SIZE = 1M; ALTER LOGFILE GROUP lg1 ADD UNDOFILE 'undofile02.dat' INITIAL_SIZE = 4M ENGINE=NDB; +set storage_engine=myisam; CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' USE LOGFILE GROUP lg1 diff --git a/mysql-test/r/ndb_restore.result b/mysql-test/r/ndb_restore.result index c745869daee..fe6a63cd582 100644 --- a/mysql-test/r/ndb_restore.result +++ b/mysql-test/r/ndb_restore.result @@ -528,6 +528,9 @@ SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID; SYSTEM_VALUES_ID VALUE 0 4767 1 6 +SELECT * FROM cluster.apply_status WHERE server_id=0; +server_id epoch +0 314 TRUNCATE GL; TRUNCATE ACCOUNT; TRUNCATE TRANSACTION; @@ -579,4 +582,7 @@ SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID; SYSTEM_VALUES_ID VALUE 0 2297 1 5 +SELECT * FROM cluster.apply_status WHERE server_id=0; +server_id epoch +0 331 DROP DATABASE BANK; diff --git a/mysql-test/t/ndb_binlog_discover.test b/mysql-test/t/ndb_binlog_discover.test new file mode 100644 index 00000000000..e74bd3380bd --- /dev/null +++ b/mysql-test/t/ndb_binlog_discover.test @@ -0,0 +1,19 @@ +-- source include/have_ndb.inc +-- source include/have_binlog_format_row.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Bug #14516 Restart of cluster can cause NDB API replication failure +# +create table t1 (a int key) engine=ndb; +reset master; +--exec $NDB_MGM --no-defaults -e "all restart -n" > /dev/null +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --not-started > /dev/null +--exec $NDB_MGM --no-defaults -e "all start" > /dev/null +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults > /dev/null +insert into t1 values(1); +--source include/show_binlog_events.inc +drop table t1; diff --git a/mysql-test/t/ndb_dd_basic.test b/mysql-test/t/ndb_dd_basic.test index 0bc0e07fad8..9df2cfb0371 100644 --- a/mysql-test/t/ndb_dd_basic.test +++ b/mysql-test/t/ndb_dd_basic.test @@ -14,16 +14,33 @@ DROP TABLE IF EXISTS t1; --enable_warnings +# some negative tests +CREATE LOGFILE GROUP lg1 +ADD UNDOFILE 'undofile.dat' +INITIAL_SIZE 16M +UNDO_BUFFER_SIZE = 1M +ENGINE=MYISAM; + +ALTER LOGFILE GROUP lg1 +ADD UNDOFILE 'undofile02.dat' +INITIAL_SIZE = 4M +ENGINE=XYZ; + +CREATE TABLESPACE ts1 +ADD DATAFILE 'datafile.dat' +USE LOGFILE GROUP lg1 +INITIAL_SIZE 12M; + ################################## # Basic test of disk tables for NDB # Start by creating a logfile group ################################## +set storage_engine=ndb; CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' INITIAL_SIZE 16M -UNDO_BUFFER_SIZE = 1M -ENGINE=NDB; +UNDO_BUFFER_SIZE = 1M; ALTER LOGFILE GROUP lg1 ADD UNDOFILE 'undofile02.dat' @@ -34,6 +51,7 @@ ENGINE=NDB; # Create a tablespace connected to the logfile group ################################################### +set storage_engine=myisam; CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' USE LOGFILE GROUP lg1 diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test index 01fdb2ecc5a..7b54358f67e 100644 --- a/mysql-test/t/ndb_restore.test +++ b/mysql-test/t/ndb_restore.test @@ -384,12 +384,13 @@ DROP DATABASE IF EXISTS BANK; CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin; USE BANK; --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -p 1 -m -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT ---exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -e -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT SHOW TABLES; SELECT * FROM GL ORDER BY TIME,ACCOUNT_TYPE; SELECT * FROM ACCOUNT ORDER BY ACCOUNT_ID; SELECT COUNT(*) FROM TRANSACTION; SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID; +SELECT * FROM cluster.apply_status WHERE server_id=0; # # verify restore of 5.0 backup @@ -402,9 +403,10 @@ TRUNCATE TRANSACTION; TRUNCATE SYSTEM_VALUES; TRUNCATE ACCOUNT_TYPE; --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup50 >> $NDB_TOOLS_OUTPUT ---exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup50 >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -e -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup50 >> $NDB_TOOLS_OUTPUT SELECT * FROM GL ORDER BY TIME,ACCOUNT_TYPE; SELECT * FROM ACCOUNT ORDER BY ACCOUNT_ID; SELECT COUNT(*) FROM TRANSACTION; SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID; +SELECT * FROM cluster.apply_status WHERE server_id=0; DROP DATABASE BANK; diff --git a/sql/handler.h b/sql/handler.h index c7c3aa54c3b..090ef1f9f30 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -402,6 +402,7 @@ enum tablespace_access_mode TS_NOT_ACCESSIBLE = 2 }; +struct handlerton; class st_alter_tablespace : public Sql_alloc { public: @@ -419,7 +420,7 @@ class st_alter_tablespace : public Sql_alloc ulonglong autoextend_size; ulonglong max_size; uint nodegroup_id; - enum legacy_db_type storage_engine; + const handlerton *storage_engine; bool wait_until_completed; const char *ts_comment; enum tablespace_access_mode ts_access_mode; @@ -437,7 +438,7 @@ class st_alter_tablespace : public Sql_alloc initial_size= 128*1024*1024; //Default 128 MByte autoextend_size= 0; //No autoextension as default max_size= 0; //Max size == initial size => no extension - storage_engine= DB_TYPE_UNKNOWN; + storage_engine= NULL; nodegroup_id= UNDEF_NODEGROUP; wait_until_completed= TRUE; ts_comment= NULL; @@ -468,7 +469,7 @@ enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX }; savepoint_*, prepare, recover, and *_by_xid pointers can be 0. */ -typedef struct +struct handlerton { /* handlerton structure version @@ -581,7 +582,7 @@ typedef struct const char *query, uint query_length, const char *db, const char *table_name); int (*release_temporary_latches)(THD *thd); -} handlerton; +}; extern const handlerton default_hton; diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc index 954d65ea44e..8bc39ec82c6 100644 --- a/sql/sql_tablespace.cc +++ b/sql/sql_tablespace.cc @@ -21,31 +21,51 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) { int error= HA_ADMIN_NOT_IMPLEMENTED; - handlerton *hton; + const handlerton *hton= ts_info->storage_engine; DBUG_ENTER("mysql_alter_tablespace"); /* If the user haven't defined an engine, this will fallback to using the default storage engine. */ - hton= ha_resolve_by_legacy_type(thd, ts_info->storage_engine); - - if (hton->state == SHOW_OPTION_YES && - hton->alter_tablespace && (error= hton->alter_tablespace(thd, ts_info))) + if (hton == NULL || hton == &default_hton || hton->state != SHOW_OPTION_YES) { - if (error == HA_ADMIN_NOT_IMPLEMENTED) + hton= ha_resolve_by_legacy_type(thd, DB_TYPE_DEFAULT); + if (ts_info->storage_engine != 0) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_WARN_USING_OTHER_HANDLER, + ER(ER_WARN_USING_OTHER_HANDLER), + hton->name, + ts_info->tablespace_name + ? ts_info->tablespace_name : ts_info->logfile_group_name); + } + + if (hton->alter_tablespace) + { + if ((error= hton->alter_tablespace(thd, ts_info))) { - my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), ""); + if (error == HA_ADMIN_NOT_IMPLEMENTED) + { + my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), ""); + } + else if (error == 1) + { + DBUG_RETURN(1); + } + else + { + my_error(error, MYF(0)); + } + DBUG_RETURN(error); } - else if (error == 1) - { - DBUG_RETURN(1); - } - else - { - my_error(error, MYF(0)); - } - DBUG_RETURN(error); + } + else + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ILLEGAL_HA_CREATE_OPTION, + ER(ER_ILLEGAL_HA_CREATE_OPTION), + hton->name, + "TABLESPACE or LOGFILE GROUP"); } if (mysql_bin_log.is_open()) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 47f0b1e259e..d533aac9850 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3187,13 +3187,13 @@ opt_ts_engine: opt_storage ENGINE_SYM opt_equal storage_engines { LEX *lex= Lex; - if (lex->alter_tablespace_info->storage_engine != DB_TYPE_UNKNOWN) + if (lex->alter_tablespace_info->storage_engine != NULL) { my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0), "STORAGE ENGINE"); YYABORT; } - lex->alter_tablespace_info->storage_engine= $4->db_type; + lex->alter_tablespace_info->storage_engine= $4 ? $4 : &default_hton; }; opt_ts_wait: diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp index 36037fba9ed..070a3baa686 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -1911,12 +1911,16 @@ NdbEventBuffer::merge_data(const SubTableData * const sdata, // loop twice where first loop only sets sizes int loop; + int result = 0; for (loop = 0; loop <= 1; loop++) { if (loop == 1) { if (alloc_mem(data, ptr) != 0) - DBUG_RETURN_EVENT(-1); + { + result = -1; + goto end; + } *data->sdata = *sdata; data->sdata->operation = tp->t3; } @@ -2030,10 +2034,13 @@ NdbEventBuffer::merge_data(const SubTableData * const sdata, } } +end: // free old data NdbMem_Free((char*)olddata.memory); + assert(m_total_alloc >= olddata.sz); + m_total_alloc -= olddata.sz; - DBUG_RETURN_EVENT(0); + DBUG_RETURN_EVENT(result); } /*