#At file:///home/lsoares/Workspace/bzr/work/bugfixing/51426/push/mysql-trunk-bugfixing/ based on revid:mattias.jonsson@stripped
2998 Luis Soares 2010-03-16
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.
modified:
mysql-test/suite/rpl/r/rpl_stm_user_variables.result
mysql-test/suite/rpl/t/rpl_stm_user_variables.test
sql/item_func.cc
sql/log.cc
sql/sql_class.h
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_user_variables.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_user_variables.result 2010-02-10 00:05:45 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_user_variables.result 2010-03-16 23:57:33 +0000
@@ -206,3 +206,19 @@ Comparing tables master:test.t1 and slav
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;
=== modified file 'mysql-test/suite/rpl/t/rpl_stm_user_variables.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_user_variables.test 2010-01-18 09:11:28 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_user_variables.test 2010-03-16 23:57:33 +0000
@@ -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
+
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2010-02-27 07:43:32 +0000
+++ b/sql/item_func.cc 2010-03-16 23:57:33 +0000
@@ -4766,6 +4766,7 @@ int get_var_with_binlog(THD *thd, enum_s
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*/
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-02-24 13:52:27 +0000
+++ b/sql/log.cc 2010-03-16 23:57:33 +0000
@@ -4671,7 +4671,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
/* 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,
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-13 10:58:27 +0000
+++ b/sql/sql_class.h 2010-03-16 23:57:33 +0000
@@ -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
Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20100316235733-drdh0kbnwgmpe1pt.bundle
Thread |
---|
• bzr commit into mysql-trunk-bugfixing branch (luis.soares:2998)Bug#49562 | Luis Soares | 17 Mar |