Commit 229da7c0 authored by Luis Soares's avatar Luis Soares

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.
parent 26a8eda4
......@@ -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;
......@@ -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
......@@ -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*/
......
......@@ -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,
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment