From: Andrei Elkin Date: April 23 2012 9:04am Subject: bzr push into mysql-5.5 branch (andrei.elkin:3798 to 3802) List-Archive: http://lists.mysql.com/commits/143623 Message-Id: <201204230904.q3N94UQ5019414@mysql1000.dsl.inet.fi> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3802 Andrei Elkin 2012-04-23 [merge] null merge from 5.1. 3801 Andrei Elkin 2012-04-21 merge bug11754117-45670 fixes from 5.1: fixing comments in sql_lex.h. modified: sql/sql_lex.h 3800 Andrei Elkin 2012-04-21 merge bug11754117-45670 fixes from 5.1: fixing result files. modified: mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result 3799 Andrei Elkin 2012-04-21 [merge] merge bug11754117-45670 fixes from 5.1. added: mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test modified: mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test sql/log_event.cc sql/log_event.h sql/rpl_rli.cc sql/rpl_rli.h sql/rpl_utility.cc sql/rpl_utility.h sql/share/errmsg-utf8.txt sql/slave.cc sql/sql_base.cc sql/sql_class.cc sql/sql_class.h sql/sql_lex.cc sql/sql_lex.h sql/sql_parse.cc 3798 Mayank Prasad 2012-04-21 BUG#12427262 : 60961: SHOW TABLES VERY SLOW WHEN NOT IN SYSTEM DISK CACHE Details: - test case bug12427262.test was failing on windows because on windows '/' was not recognized. And this was used in LIKE clause of the query being run in this test case. Fix: - Windows needs '\\\\' for path seperater in mysql. I was not sure how to keep a single query with two different syntax based on platform. So modifying query to make sure it runs correctly on both platform. modified: mysql-test/r/bug12427262.result mysql-test/t/bug12427262.test === added file 'mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result' --- a/mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/r/rpl_auto_increment_bug45679.result 2012-04-23 08:56:23 +0000 @@ -0,0 +1,41 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.'); +create table tm (b int auto_increment, a int, primary key (a,b)) engine= myisam; +create table ti (b int auto_increment, a int, primary key (a,b)) engine= innodb; +ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key +create table ti (b int auto_increment, a int, primary key (b,a)) engine= innodb; +set @@binlog_format=statement; +*** autoincrement field is not the first in PK warning must be there: *** +insert into tm set b=null, a=1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe. +show warnings; +Level Code Message +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe. +*** no warning when autoincrement is the first in PK +insert into ti set b=null, a=1; +show warnings; +Level Code Message +create function multi_part_pk_with_autoinc (arg int) +returns int +begin +insert into tm set b=null, a=arg; +return arg; +end// +select multi_part_pk_with_autoinc (3); +multi_part_pk_with_autoinc (3) +3 +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly. +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe. +*** autoincrement field is not the first in PK warning must be there: *** +show warnings; +Level Code Message +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly. +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT into autoincrement field which is not the first part in the composed primary key is unsafe. +set @@binlog_format=mixed; +insert into tm set b=null, a=2; +drop table tm, ti; +drop function multi_part_pk_with_autoinc; +include/rpl_end.inc === modified file 'mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result' --- a/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result 2011-02-23 09:31:37 +0000 +++ b/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result 2012-04-21 11:19:06 +0000 @@ -114,4 +114,25 @@ id c 3 3 [on master] drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); +CREATE TABLE test.t1 (a INT); +INSERT INTO test.t1 VALUES(1); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); +CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW +INSERT INTO test.t_slave VALUES(NULL, ROUND(RAND() * 1000), @c); +SET INSERT_ID=2; +SET @c=2; +SET @@rand_seed1=10000000, @@rand_seed2=1000000; +INSERT INTO t5 VALUES (NULL, ROUND(RAND() * 1000), @c); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. +SELECT b into @b FROM test.t5; +UPDATE test.t1 SET a=2; +SELECT a AS 'ONE' into @a FROM test.t_slave; +SELECT c AS 'NULL' into @c FROM test.t_slave; +SELECT b into @b FROM test.t_slave; +drop table test.t5; +drop table test.t1; +drop table test.t_slave; include/rpl_end.inc === added file 'mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test' --- a/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test 2012-04-23 08:56:23 +0000 @@ -0,0 +1,62 @@ +# Test of auto-increment. +# +# BUG#11754117-45670 +# Multipart primary key with the autoincrement part not first in it +# is replication unsafe. +# + +source include/master-slave.inc; +source include/have_binlog_format_mixed.inc; +source include/have_innodb.inc; + +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.'); + +--connection master +create table tm (b int auto_increment, a int, primary key (a,b)) engine= myisam; +--error ER_WRONG_AUTO_KEY +create table ti (b int auto_increment, a int, primary key (a,b)) engine= innodb; +create table ti (b int auto_increment, a int, primary key (b,a)) engine= innodb; + +set @@binlog_format=statement; +--echo *** autoincrement field is not the first in PK warning must be there: *** +insert into tm set b=null, a=1; +show warnings; +--echo *** no warning when autoincrement is the first in PK +insert into ti set b=null, a=1; +show warnings; + +delimiter //; +create function multi_part_pk_with_autoinc (arg int) +returns int +begin + insert into tm set b=null, a=arg; + return arg; +end// +delimiter ;// + +select multi_part_pk_with_autoinc (3); +--echo *** autoincrement field is not the first in PK warning must be there: *** +show warnings; + +set @@binlog_format=mixed; +insert into tm set b=null, a=2; + +sync_slave_with_master; + +if (`select count(*) <> 3 from tm`) +{ + --echo Wrong result from SELECT on the slave side. + select * from tm; + --die +} + +# cleanup + +--connection master + +drop table tm, ti; +drop function multi_part_pk_with_autoinc; + +sync_slave_with_master; + +--source include/rpl_end.inc === modified file 'mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test' --- a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test 2011-02-23 09:31:37 +0000 +++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test 2012-04-20 16:41:20 +0000 @@ -206,4 +206,64 @@ SELECT * FROM t3; connection master; echo [on master]; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; + +--sync_slave_with_master + +# +# BUG#11754117 - 45670: INTVAR_EVENTS FOR FILTERED-OUT QUERY_LOG_EVENTS ARE EXECUTED +# Int-, Rand- and User- var events accompaning a filtered out Query-log-event should +# be filtered as well. +# +connection master; +CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); # ignored on slave +CREATE TABLE test.t1 (a INT); # accepted on slave +INSERT INTO test.t1 VALUES(1); + +--sync_slave_with_master +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); +CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW + INSERT INTO test.t_slave VALUES(NULL, ROUND(RAND() * 1000), @c); + +connection master; +SET INSERT_ID=2; +SET @c=2; +SET @@rand_seed1=10000000, @@rand_seed2=1000000; +INSERT INTO t5 VALUES (NULL, ROUND(RAND() * 1000), @c); # to be ignored +SELECT b into @b FROM test.t5; +--let $b_master=`select @b` +UPDATE test.t1 SET a=2; # to run trigger on slave + +--sync_slave_with_master + +# The proof: +SELECT a AS 'ONE' into @a FROM test.t_slave; +SELECT c AS 'NULL' into @c FROM test.t_slave; + +let $count= 1; +let $table= test.t_slave; +source include/wait_until_rows_count.inc; + +if (`SELECT @a != 2 and @c != NULL`) +{ + SELECT * FROM test.t_slave; + --die Intvar or user var from replication events unexpetedly escaped out to screw a following query applying context. +} + +SELECT b into @b FROM test.t_slave; +--let $b_slave=`select @b` + +if (`SELECT $b_slave = $b_master`) +{ + --echo Might be pure coincidence of two randoms from master and slave table. Don not panic yet. +} + +# cleanup BUG#11754117 +connection master; +drop table test.t5; +drop table test.t1; + +--sync_slave_with_master +drop table test.t_slave; + --source include/rpl_end.inc === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2012-04-12 05:37:39 +0000 +++ b/sql/log_event.cc 2012-04-21 10:24:39 +0000 @@ -5372,11 +5372,12 @@ void Intvar_log_event::print(FILE* file, #endif +#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT) + /* Intvar_log_event::do_apply_event() */ -#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT) int Intvar_log_event::do_apply_event(Relay_log_info const *rli) { /* @@ -5385,6 +5386,9 @@ int Intvar_log_event::do_apply_event(Rel */ const_cast(rli)->set_flag(Relay_log_info::IN_STMT); + if (rli->deferred_events_collecting) + return rli->deferred_events->add(this); + switch (type) { case LAST_INSERT_ID_EVENT: thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1; @@ -5490,6 +5494,9 @@ int Rand_log_event::do_apply_event(Relay */ const_cast(rli)->set_flag(Relay_log_info::IN_STMT); + if (rli->deferred_events_collecting) + return rli->deferred_events->add(this); + thd->rand.seed1= (ulong) seed1; thd->rand.seed2= (ulong) seed2; return 0; @@ -5516,6 +5523,29 @@ Rand_log_event::do_shall_skip(Relay_log_ return continue_group(rli); } +/** + Exec deferred Int-, Rand- and User- var events prefixing + a Query-log-event event. + + @param thd THD handle + + @return false on success, true if a failure in an event applying occurred. +*/ +bool slave_execute_deferred_events(THD *thd) +{ + bool res= false; + Relay_log_info *rli= thd->rli_slave; + + DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events)); + + if (!rli->deferred_events_collecting || rli->deferred_events->is_empty()) + return res; + + res= rli->deferred_events->execute(rli); + + return res; +} + #endif /* !MYSQL_CLIENT */ @@ -5939,6 +5969,10 @@ int User_var_log_event::do_apply_event(R { Item *it= 0; CHARSET_INFO *charset; + + if (rli->deferred_events_collecting) + return rli->deferred_events->add(this); + if (!(charset= get_charset(charset_number, MYF(MY_WME)))) return 1; LEX_STRING user_var_name; === modified file 'sql/log_event.h' --- a/sql/log_event.h 2012-02-29 08:45:15 +0000 +++ b/sql/log_event.h 2012-04-21 10:24:39 +0000 @@ -4080,11 +4080,18 @@ private: const char* log_ident; uint ident_len; }; + +/** + The function is called by slave applier in case there are + active table filtering rules to force gathering events associated + with Query-log-event into an array to execute + them once the fate of the Query is determined for execution. +*/ +bool slave_execute_deferred_events(THD *thd); #endif int append_query_string(THD *thd, CHARSET_INFO *csinfo, String const *from, String *to); - /** @} (end of group Replication) */ === modified file 'sql/rpl_rli.cc' --- a/sql/rpl_rli.cc 2012-02-16 09:48:16 +0000 +++ b/sql/rpl_rli.cc 2012-04-21 10:24:39 +0000 @@ -52,8 +52,8 @@ Relay_log_info::Relay_log_info(bool is_s inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE), until_log_pos(0), retried_trans(0), tables_to_lock(0), tables_to_lock_count(0), - last_event_start_time(0), m_flags(0), row_stmt_start_timestamp(0), - long_find_row_note_printed(false) + last_event_start_time(0), deferred_events(NULL),m_flags(0), + row_stmt_start_timestamp(0), long_find_row_note_printed(false) { DBUG_ENTER("Relay_log_info::Relay_log_info"); === modified file 'sql/rpl_rli.h' --- a/sql/rpl_rli.h 2012-03-12 22:02:50 +0000 +++ b/sql/rpl_rli.h 2012-04-21 10:24:39 +0000 @@ -388,6 +388,41 @@ public: */ time_t last_event_start_time; + /* + A container to hold on Intvar-, Rand-, Uservar- log-events in case + the slave is configured with table filtering rules. + The withhold events are executed when their parent Query destiny is + determined for execution as well. + */ + Deferred_log_events *deferred_events; + + /* + State of the container: true stands for IRU events gathering, + false does for execution, either deferred or direct. + */ + bool deferred_events_collecting; + + /* + Returns true if the argument event resides in the containter; + more specifically, the checking is done against the last added event. + */ + bool is_deferred_event(Log_event * ev) + { + return deferred_events_collecting ? deferred_events->is_last(ev) : false; + }; + /* The general cleanup that slave applier may need at the end of query. */ + inline void cleanup_after_query() + { + if (deferred_events) + deferred_events->rewind(); + }; + /* The general cleanup that slave applier may need at the end of session. */ + void cleanup_after_session() + { + if (deferred_events) + delete deferred_events; + }; + /** Helper function to do after statement completion. === modified file 'sql/rpl_utility.cc' --- a/sql/rpl_utility.cc 2011-06-30 15:46:53 +0000 +++ b/sql/rpl_utility.cc 2012-04-21 10:24:39 +0000 @@ -18,6 +18,7 @@ #ifndef MYSQL_CLIENT #include "unireg.h" // REQUIRED by later includes #include "rpl_rli.h" +#include "log_event.h" #include "sql_select.h" /** @@ -1056,3 +1057,65 @@ table_def::~table_def() #endif } + +#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) + +Deferred_log_events::Deferred_log_events(Relay_log_info *rli) : last_added(NULL) +{ + my_init_dynamic_array(&array, sizeof(Log_event *), 32, 16); +} + +Deferred_log_events::~Deferred_log_events() +{ + delete_dynamic(&array); +} + +int Deferred_log_events::add(Log_event *ev) +{ + last_added= ev; + insert_dynamic(&array, (uchar*) &ev); + return 0; +} + +bool Deferred_log_events::is_empty() +{ + return array.elements == 0; +} + +bool Deferred_log_events::execute(Relay_log_info *rli) +{ + bool res= false; + + DBUG_ASSERT(rli->deferred_events_collecting); + + rli->deferred_events_collecting= false; + for (uint i= 0; !res && i < array.elements; i++) + { + Log_event *ev= (* (Log_event **) + dynamic_array_ptr(&array, i)); + res= ev->apply_event(rli); + } + rli->deferred_events_collecting= true; + return res; +} + +void Deferred_log_events::rewind() +{ + /* + Reset preceeding Query log event events which execution was + deferred because of slave side filtering. + */ + if (!is_empty()) + { + for (uint i= 0; i < array.elements; i++) + { + Log_event *ev= *(Log_event **) dynamic_array_ptr(&array, i); + delete ev; + } + if (array.elements > array.max_element) + freeze_size(&array); + reset_dynamic(&array); + } +} + +#endif === modified file 'sql/rpl_utility.h' --- a/sql/rpl_utility.h 2011-06-30 15:46:53 +0000 +++ b/sql/rpl_utility.h 2012-04-21 10:24:39 +0000 @@ -28,7 +28,7 @@ #include "mysql_com.h" class Relay_log_info; - +class Log_event; /** A table definition from the master. @@ -261,6 +261,24 @@ CPP_UNNAMED_NS_START }; CPP_UNNAMED_NS_END + +class Deferred_log_events +{ +private: + DYNAMIC_ARRAY array; + Log_event *last_added; + +public: + Deferred_log_events(Relay_log_info *rli); + ~Deferred_log_events(); + /* queue for exection at Query-log-event time prior the Query */; + int add(Log_event *ev); + bool is_empty(); + bool execute(Relay_log_info *rli); + void rewind(); + bool is_last(Log_event *ev) { return ev == last_added; }; +}; + #endif // NB. number of printed bit values is limited to sizeof(buf) - 1 === modified file 'sql/share/errmsg-utf8.txt' --- a/sql/share/errmsg-utf8.txt 2012-04-11 10:23:17 +0000 +++ b/sql/share/errmsg-utf8.txt 2012-04-21 10:24:39 +0000 @@ -6500,6 +6500,9 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS ER_UNSUPPORTED_ENGINE eng "Storage engine '%s' does not support system tables. [%s.%s]" +ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST + eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe." + # # End of 5.5 error messages. # === modified file 'sql/slave.cc' --- a/sql/slave.cc 2012-03-12 22:02:50 +0000 +++ b/sql/slave.cc 2012-04-21 10:24:39 +0000 @@ -2557,7 +2557,8 @@ static int exec_relay_log_event(THD* thd used to read info about the relay log's format; it will be deleted when the SQL thread does not need it, i.e. when this thread terminates. */ - if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT) + if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT && + !rli->is_deferred_event(ev)) { DBUG_PRINT("info", ("Deleting the event after it has been executed")); delete ev; @@ -3219,6 +3220,12 @@ pthread_handler_t handle_slave_sql(void goto err; } thd->init_for_queries(); + thd->rli_slave= rli; + if ((rli->deferred_events_collecting= rpl_filter->is_on())) + { + rli->deferred_events= new Deferred_log_events(rli); + } + thd->temporary_tables = rli->save_temporary_tables; // restore temp tables set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables mysql_mutex_lock(&LOCK_thread_count); === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2012-04-02 19:05:43 +0000 +++ b/sql/sql_base.cc 2012-04-21 10:24:39 +0000 @@ -216,6 +216,7 @@ static bool has_write_table_with_auto_increment(TABLE_LIST *tables); static bool has_write_table_with_auto_increment_and_select(TABLE_LIST *tables); +static bool has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables); uint cached_open_tables(void) { @@ -5690,6 +5691,12 @@ bool lock_tables(THD *thd, TABLE_LIST *t if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables && has_write_table_with_auto_increment_and_select(tables)) thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT); + /* Todo: merge all has_write_table_auto_inc with decide_logging_format */ + if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables) + { + if (has_write_table_auto_increment_not_first_in_pk(tables)) + thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST); + } /* INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys @@ -9152,6 +9159,32 @@ has_write_table_with_auto_increment_and_ return(has_select && has_auto_increment_tables); } +/* + Tells if there is a table whose auto_increment column is a part + of a compound primary key while is not the first column in + the table definition. + + @param tables Table list + + @return true if the table exists, fais if does not. +*/ + +static bool +has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables) +{ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + /* we must do preliminary checks as table->table may be NULL */ + if (!table->placeholder() && + table->table->found_next_number_field && + (table->lock_type >= TL_WRITE_ALLOW_WRITE) + && table->table->s->next_number_keypart != 0) + return 1; + } + + return 0; +} + /* === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2012-02-17 09:57:45 +0000 +++ b/sql/sql_class.cc 2012-04-21 10:24:39 +0000 @@ -744,7 +744,7 @@ bool Drop_table_error_handler::handle_co THD::THD() :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, /* statement id */ 0), - rli_fake(0), + rli_fake(0), rli_slave(NULL), user_time(0), in_sub_stmt(0), binlog_unsafe_warning_flags(0), binlog_table_maps(0), @@ -1359,6 +1359,8 @@ THD::~THD() } mysql_audit_free_thd(this); + if (rli_slave) + rli_slave->cleanup_after_session(); #endif free_root(&main_mem_root, MYF(0)); @@ -1678,6 +1680,10 @@ void THD::cleanup_after_query() { delete_dynamic(&lex->mi.repl_ignore_server_ids); } +#ifndef EMBEDDED_LIBRARY + if (rli_slave) + rli_slave->cleanup_after_query(); +#endif } === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2011-11-10 06:43:34 +0000 +++ b/sql/sql_class.h 2012-04-21 10:24:39 +0000 @@ -1445,6 +1445,8 @@ public: /* Used to execute base64 coded binlog events in MySQL server */ Relay_log_info* rli_fake; + /* Slave applier execution context */ + Relay_log_info* rli_slave; void reset_for_next_command(); /* === modified file 'sql/sql_lex.cc' --- a/sql/sql_lex.cc 2012-04-18 11:15:27 +0000 +++ b/sql/sql_lex.cc 2012-04-21 10:24:39 +0000 @@ -67,7 +67,8 @@ Query_tables_list::binlog_stmt_unsafe_er ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT, ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC, ER_BINLOG_UNSAFE_UPDATE_IGNORE, - ER_BINLOG_UNSAFE_INSERT_TWO_KEYS + ER_BINLOG_UNSAFE_INSERT_TWO_KEYS, + ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST }; === modified file 'sql/sql_lex.h' --- a/sql/sql_lex.h 2012-04-18 11:15:27 +0000 +++ b/sql/sql_lex.h 2012-04-21 12:06:06 +0000 @@ -1329,6 +1329,12 @@ public: */ BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS, + /** + INSERT into auto-inc field which is not the first part of composed + primary key. + */ + BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST, + /* The last element of this enumeration type. */ BINLOG_STMT_UNSAFE_COUNT }; === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2012-04-18 09:12:19 +0000 +++ b/sql/sql_parse.cc 2012-04-21 10:24:39 +0000 @@ -2025,6 +2025,11 @@ mysql_execute_command(THD *thd) } DBUG_RETURN(0); } + /* + Execute deferred events first + */ + if (slave_execute_deferred_events(thd)) + DBUG_RETURN(-1); } else { No bundle (reason: useless for push emails).