diff options
author | Luis Soares <luis.soares@sun.com> | 2010-03-17 00:06:13 +0000 |
---|---|---|
committer | Luis Soares <luis.soares@sun.com> | 2010-03-17 00:06:13 +0000 |
commit | 92b5e586758de97ebf3272e337b965d43cdf571c (patch) | |
tree | 5100e704c6b5312c7170166f1217fcfea545441d | |
parent | 5937da69a6d5b3461373dfc7abd8d003f4013fce (diff) | |
download | mariadb-git-92b5e586758de97ebf3272e337b965d43cdf571c.tar.gz |
BUG#51426: overflow for auto_increment column causes slave to stop
In BUG#49562 we fixed the case where numeric user var events
would not serialize the flag stating whether the value was signed
or unsigned (unsigned_flag). This fixed the case that the slave
would get an overflow while treating the unsigned values as
signed.
In this bug, we find that the unsigned_flag can sometimes change
between the moment that the user value is recorded for binlogging
purposes and the actual binlogging time. Since we take the
unsigned_flag from the runtime variable data, at binlogging time,
and the variable value is comes from the copy taken earlier in
the execution, there may be inconsistency in the
User_var_log_event between the variable value and its
unsigned_flag.
We fix this by also copying the unsigned_flag of the
user_var_entry when its value is copied, for binlogging
purposes. Later, at binlogging time, we use the copied
unsigned_flag and not the one in the runtime user_var_entry
instance.
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_stm_user_variables.result | 16 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_stm_user_variables.test | 33 | ||||
-rw-r--r-- | sql/item_func.cc | 1 | ||||
-rw-r--r-- | sql/log.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 1 |
5 files changed, 52 insertions, 1 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_stm_user_variables.result b/mysql-test/suite/rpl/r/rpl_stm_user_variables.result index 5e758fc02f3..8f43425b201 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_user_variables.result +++ b/mysql-test/suite/rpl/r/rpl_stm_user_variables.result @@ -206,3 +206,19 @@ Comparing tables master:test.t1 and slave:test.t1 TRUNCATE t1; ## check: contents of both tables master's and slave's DROP TABLE t1; +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +CREATE TABLE t1 ( c INT, PRIMARY KEY (c)) Engine=MyISAM; +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW SET @aux = -1 ; +SET @aux = 10294947273192243200; +SET @aux1= @aux; +INSERT INTO t1 VALUES (@aux) , (@aux1); +ERROR 23000: Duplicate entry '2147483647' for key 'PRIMARY' +## assertion: master and slave tables are in sync +Comparing tables master:test.t1 and slave:test.t1 +DROP TRIGGER tr1; +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_stm_user_variables.test b/mysql-test/suite/rpl/t/rpl_stm_user_variables.test index c58acdcb084..05adc597776 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_user_variables.test +++ b/mysql-test/suite/rpl/t/rpl_stm_user_variables.test @@ -139,3 +139,36 @@ TRUNCATE t1; -- connection master DROP TABLE t1; -- sync_slave_with_master + +##################################################################### +# +# BUG#51426 +# +##################################################################### +-- source include/master-slave-reset.inc +-- connection master + +CREATE TABLE t1 ( c INT, PRIMARY KEY (c)) Engine=MyISAM; + +# offending trigger that would reset the unsigned flag for aux before +# binlogging of User_var_log_event would take place. +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW SET @aux = -1 ; + +SET @aux = 10294947273192243200; +SET @aux1= @aux; +-- error ER_DUP_ENTRY +INSERT INTO t1 VALUES (@aux) , (@aux1); + +-- sync_slave_with_master + +-- echo ## assertion: master and slave tables are in sync +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +--connection master +DROP TRIGGER tr1; +DROP TABLE t1; + +-- sync_slave_with_master + diff --git a/sql/item_func.cc b/sql/item_func.cc index ca8f5d00bb1..391ddfa4a7c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4766,6 +4766,7 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command, user_var_event->user_var_event= var_entry; user_var_event->type= var_entry->type; user_var_event->charset_number= var_entry->collation.collation->number; + user_var_event->unsigned_flag= var_entry->unsigned_flag; if (!var_entry->value) { /* NULL value*/ diff --git a/sql/log.cc b/sql/log.cc index ce9d75089d1..279782d271b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4671,7 +4671,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) /* setting flags for user var log event */ uchar flags= User_var_log_event::UNDEF_F; - if (user_var_event->user_var_event->unsigned_flag) + if (user_var_event->unsigned_flag) flags|= User_var_log_event::UNSIGNED_F; User_var_log_event e(thd, user_var_event->user_var_event->name.str, diff --git a/sql/sql_class.h b/sql/sql_class.h index f8e8942e244..de6d92eccfd 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -75,6 +75,7 @@ typedef struct st_user_var_events ulong length; Item_result type; uint charset_number; + bool unsigned_flag; } BINLOG_USER_VAR_EVENT; #define RP_LOCK_LOG_IS_ALREADY_LOCKED 1 |