diff options
-rw-r--r-- | mysql-test/r/create.result | 6 | ||||
-rw-r--r-- | mysql-test/r/innodb_mysql.result | 6 | ||||
-rw-r--r-- | mysql-test/t/create.test | 8 | ||||
-rw-r--r-- | mysql-test/t/innodb_mysql.test | 9 | ||||
-rw-r--r-- | mysql-test/t/rpl_rbr_to_sbr.test | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_row_basic_8partition.test | 1 | ||||
-rw-r--r-- | sql/log.cc | 15 | ||||
-rw-r--r-- | sql/set_var.cc | 10 | ||||
-rw-r--r-- | sql/set_var.h | 9 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 13 | ||||
-rw-r--r-- | sql/sql_class.h | 23 | ||||
-rw-r--r-- | sql/sql_insert.cc | 10 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 |
16 files changed, 93 insertions, 27 deletions
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index d45960cf787..41baeedf3f8 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -772,9 +772,3 @@ t1 CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=4294967295 drop table t1; -create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb -character set utf8 collate utf8_general_ci; -Warnings: -Warning 1071 Specified key was too long; max key length is 765 bytes -insert into t1 values('aaa'); -drop table t1; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 878c5cb5451..212e352390f 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1 +1,7 @@ drop table if exists t1; +create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb +character set utf8 collate utf8_general_ci; +Warnings: +Warning 1071 Specified key was too long; max key length is 765 bytes +insert into t1 values('aaa'); +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index fe8cfe70c4e..9b1b7a33029 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -667,12 +667,4 @@ alter table t1 max_rows=100000000000; show create table t1; drop table t1; -# -# Bug#17530: Incorrect key truncation on table creation caused server crash. -# -create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb - character set utf8 collate utf8_general_ci; -insert into t1 values('aaa'); -drop table t1; - # End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index b942b9fbc0d..f4eac1094b0 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -3,3 +3,12 @@ --disable_warnings drop table if exists t1; --enable_warnings + +# +# Bug#17530: Incorrect key truncation on table creation caused server crash. +# +create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb + character set utf8 collate utf8_general_ci; +insert into t1 values('aaa'); +drop table t1; + diff --git a/mysql-test/t/rpl_rbr_to_sbr.test b/mysql-test/t/rpl_rbr_to_sbr.test index f04caf05057..c10199f8ff5 100644 --- a/mysql-test/t/rpl_rbr_to_sbr.test +++ b/mysql-test/t/rpl_rbr_to_sbr.test @@ -1,3 +1,4 @@ +-- source include/have_row_based.inc -- source include/have_binlog_format_statement.inc -- source include/master-slave.inc diff --git a/mysql-test/t/rpl_row_basic_8partition.test b/mysql-test/t/rpl_row_basic_8partition.test index 8cad2226d4a..640a420c10e 100644 --- a/mysql-test/t/rpl_row_basic_8partition.test +++ b/mysql-test/t/rpl_row_basic_8partition.test @@ -7,6 +7,7 @@ # partition tables with same engine (MyISAM) in both ends. # ############################################################ +--source include/have_row_based.inc --source include/have_partition.inc --source include/master-slave.inc connection master; diff --git a/sql/log.cc b/sql/log.cc index 7c8f314bc08..2141f34d798 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -63,11 +63,17 @@ static int binlog_prepare(THD *thd, bool all); struct binlog_trx_data { bool empty() const { +#ifdef HAVE_ROW_BASED_REPLICATION return pending == NULL && my_b_tell(&trans_log) == 0; +#else + return my_b_tell(&trans_log) == 0; +#endif } binlog_trx_data() {} IO_CACHE trans_log; // The transaction cache +#ifdef HAVE_ROW_BASED_REPLICATION Rows_log_event *pending; // The pending binrows event +#endif }; static const char binlog_hton_name[]= "binlog"; @@ -1090,9 +1096,12 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev) were, we would have to ensure that we're not ending a statement inside a stored function. */ +#ifdef HAVE_ROW_BASED_REPLICATION thd->binlog_flush_pending_rows_event(TRUE); +#endif error= mysql_bin_log.write(thd, trans_log, end_ev); } +#ifdef HAVE_ROW_BASED_REPLICATION else { thd->binlog_delete_pending_rows_event(); @@ -1110,6 +1119,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev) transaction cache. */ mysql_bin_log.update_table_map_version(); +#endif statistic_increment(binlog_cache_use, &LOCK_status); if (trans_log->disk_writes != 0) @@ -2655,6 +2665,7 @@ int THD::binlog_setup_trx_data() engine has registered for the transaction. */ +#ifdef HAVE_ROW_BASED_REPLICATION int THD::binlog_write_table_map(TABLE *table, bool is_trans) { int error; @@ -2797,6 +2808,7 @@ int MYSQL_LOG::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event) DBUG_RETURN(error); } +#endif // HAVE_ROW_BASED_REPLICATION /* Write an event to the binary log @@ -2829,9 +2841,11 @@ bool MYSQL_LOG::write(Log_event *event_info) we are inside a stored function, we do not end the statement since this will close all tables on the slave. */ +#ifdef HAVE_ROW_BASED_REPLICATION bool const end_stmt= thd->prelocked_mode && thd->lex->requires_prelocking(); thd->binlog_flush_pending_rows_event(end_stmt); +#endif // HAVE_ROW_BASED_REPLICATION pthread_mutex_lock(&LOCK_log); @@ -2880,7 +2894,6 @@ bool MYSQL_LOG::write(Log_event *event_info) (binlog_trx_data*) thd->ha_data[binlog_hton.slot]; IO_CACHE *trans_log= &trx_data->trans_log; bool trans_log_in_use= my_b_tell(trans_log) != 0; - if (event_info->get_cache_stmt() && !trans_log_in_use) trans_register_ha(thd, (thd->options & diff --git a/sql/set_var.cc b/sql/set_var.cc index ae45b299196..e478bff722c 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1269,7 +1269,14 @@ bool sys_var_thd_binlog_format::is_readonly() const if global or not here. And this test will also prevent switching from RBR to RBR (a no-op which should not happen too often). + + If we don't have row-based replication compiled in, the variable + is always read-only. */ +#ifndef HAVE_ROW_BASED_REPLICATION + my_error(ER_RBR_NOT_AVAILABLE, MYF(0)); + return 1; +#else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) && thd->temporary_tables) { @@ -1295,12 +1302,15 @@ bool sys_var_thd_binlog_format::is_readonly() const } #endif return sys_var_thd_enum::is_readonly(); +#endif } +#ifdef HAVE_ROW_BASED_REPLICATION void fix_binlog_format_after_update(THD *thd, enum_var_type type) { thd->reset_current_stmt_binlog_row_based(); } +#endif static void fix_max_binlog_size(THD *thd, enum_var_type type) { diff --git a/sql/set_var.h b/sql/set_var.h index 8076f10bb0a..d52b2720918 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -851,15 +851,20 @@ public: bool update(THD *thd, set_var *var); }; +#ifdef HAVE_ROW_BASED_REPLICATION extern void fix_binlog_format_after_update(THD *thd, enum_var_type type); +#endif class sys_var_thd_binlog_format :public sys_var_thd_enum { public: sys_var_thd_binlog_format(const char *name_arg, ulong SV::*offset_arg) :sys_var_thd_enum(name_arg, offset_arg, - &binlog_format_typelib, - fix_binlog_format_after_update) + &binlog_format_typelib +#ifdef HAVE_ROW_BASED_REPLICATION + , fix_binlog_format_after_update +#endif + ) {}; bool is_readonly() const; }; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index a2bc77714bb..864df32f9f5 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5842,3 +5842,5 @@ ER_WRONG_PARTITION_NAME swe "Felaktigt partitionsnamn" ER_CANT_CHANGE_TX_ISOLATION 25001 eng "Transaction isolation level can't be changed while a transaction is in progress" +ER_RBR_NOT_AVAILABLE + eng "The server was not built with row-based replication" diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 77d2b165881..151af58780a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1069,7 +1069,9 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) handled either before writing a query log event (inside binlog_query()) or when preparing a pending event. */ +#ifdef HAVE_ROW_BASED_REPLICATION thd->binlog_flush_pending_rows_event(TRUE); +#endif mysql_unlock_tables(thd, thd->lock); thd->lock=0; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 6166771e5d1..6bfcc4e2c23 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -197,7 +197,10 @@ THD::THD() :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0), Open_tables_state(refresh_version), rli_fake(0), lock_id(&main_lock_id), - user_time(0), in_sub_stmt(0), binlog_table_maps(0), + user_time(0), in_sub_stmt(0), +#ifdef HAVE_ROW_BASED_REPLICATION + binlog_table_maps(0), +#endif global_read_lock(0), is_fatal_error(0), rand_used(0), time_zone_used(0), last_insert_id_used(0), insert_id_used(0), clear_next_insert_id(0), @@ -2110,7 +2113,9 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !current_stmt_binlog_row_based) + { options&= ~OPTION_BIN_LOG; + } /* Disable result sets */ client_capabilities &= ~CLIENT_MULTI_RESULTS; in_sub_stmt|= new_state; @@ -2699,6 +2704,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, to how you treat this. */ case THD::ROW_QUERY_TYPE: +#ifdef HAVE_ROW_BASED_REPLICATION if (current_stmt_binlog_row_based) { /* @@ -2717,6 +2723,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, DBUG_RETURN(binlog_flush_pending_rows_event(TRUE)); DBUG_RETURN(0); } +#endif /* Otherwise, we fall through */ case THD::STMT_QUERY_TYPE: /* @@ -2725,7 +2732,9 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, */ { Query_log_event qinfo(this, query, query_len, is_trans, suppress_use); +#ifdef HAVE_ROW_BASED_REPLICATION qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; +#endif /* Binlog table maps will be irrelevant after a Query_log_event (they are just removed on the slave side) so after the query @@ -2733,7 +2742,9 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, table maps were written. */ int error= mysql_bin_log.write(&qinfo); +#ifdef HAVE_ROW_BASED_REPLICATION binlog_table_maps= 0; +#endif DBUG_RETURN(error); } break; diff --git a/sql/sql_class.h b/sql/sql_class.h index 54f256997d0..56ddc7702f8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -890,8 +890,10 @@ public: /* container for handler's private per-connection data */ void *ha_data[MAX_HA]; -#ifdef HAVE_ROW_BASED_REPLICATION #ifndef MYSQL_CLIENT + int binlog_setup_trx_data(); + +#ifdef HAVE_ROW_BASED_REPLICATION /* Public interface to write RBR events to the binlog @@ -921,7 +923,6 @@ public: RowsEventT* hint); Rows_log_event* binlog_get_pending_rows_event() const; void binlog_set_pending_rows_event(Rows_log_event* ev); - int binlog_setup_trx_data(); my_size_t max_row_length_blob(TABLE* table, const byte *data) const; my_size_t max_row_length(TABLE* table, const byte *data) const @@ -945,8 +946,9 @@ private: public: -#endif #endif /* HAVE_ROW_BASED_REPLICATION */ +#endif /* MYSQL_CLIENT */ + #ifndef MYSQL_CLIENT enum enum_binlog_query_type { /* @@ -1380,18 +1382,25 @@ public: void restore_sub_statement_state(Sub_statement_state *backup); void set_n_backup_active_arena(Query_arena *set, Query_arena *backup); void restore_active_arena(Query_arena *set, Query_arena *backup); +#ifdef HAVE_ROW_BASED_REPLICATION inline void set_current_stmt_binlog_row_based_if_mixed() { if (variables.binlog_format == BINLOG_FORMAT_MIXED) - current_stmt_binlog_row_based= 1; + current_stmt_binlog_row_based= TRUE; } inline void set_current_stmt_binlog_row_based() { - current_stmt_binlog_row_based= 1; + current_stmt_binlog_row_based= TRUE; } +#endif inline void reset_current_stmt_binlog_row_based() { - current_stmt_binlog_row_based= test(variables.binlog_format == BINLOG_FORMAT_ROW); +#ifdef HAVE_ROW_BASED_REPLICATION + current_stmt_binlog_row_based= + test(variables.binlog_format == BINLOG_FORMAT_ROW); +#else + current_stmt_binlog_row_based= FALSE; +#endif } }; @@ -1584,7 +1593,9 @@ public: {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); +#ifdef HAVE_ROW_BASED_REPLICATION void binlog_show_create_table(TABLE **tables, uint count); +#endif void store_values(List<Item> &values); void send_error(uint errcode,const char *err); bool send_eof(); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 946c0536897..aed8b12d2c1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2523,6 +2523,8 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) { DBUG_ENTER("select_create::prepare"); + TABLEOP_HOOKS *hook_ptr= NULL; +#ifdef HAVE_ROW_BASED_REPLICATION class MY_HOOKS : public TABLEOP_HOOKS { public: MY_HOOKS(select_create *x) : ptr(x) { } @@ -2537,11 +2539,14 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) }; MY_HOOKS hooks(this); + hook_ptr= &hooks; +#endif unit= u; table= create_table_from_items(thd, create_info, create_table, extra_fields, keys, &values, &lock, - &hooks); + hook_ptr); + if (!table) DBUG_RETURN(-1); // abort() deletes table @@ -2579,6 +2584,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) } +#ifdef HAVE_ROW_BASED_REPLICATION void select_create::binlog_show_create_table(TABLE **tables, uint count) { @@ -2622,7 +2628,7 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) /* is_trans */ TRUE, /* suppress_use */ FALSE); } - +#endif // HAVE_ROW_BASED_REPLICATION void select_create::store_values(List<Item> &values) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8ee78578631..a0fda91fa9e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2468,8 +2468,10 @@ mysql_execute_command(THD *thd) statistic_increment(thd->status_var.com_stat[lex->sql_command], &LOCK_status); +#ifdef HAVE_ROW_BASED_REPLICATION if (lex->binlog_row_based_if_mixed) thd->set_current_stmt_binlog_row_based_if_mixed(); +#endif switch (lex->sql_command) { case SQLCOM_SELECT: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f890f504952..f59ab2e9811 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3507,7 +3507,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, save us from that ? */ table->reginfo.lock_type=TL_WRITE; - hooks->prelock(&table, 1); // Call prelock hooks + if (hooks) + hooks->prelock(&table, 1); // Call prelock hooks if (! ((*lock)= mysql_lock_tables(thd, &table, 1, MYSQL_LOCK_IGNORE_FLUSH, ¬_used))) { |