List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:March 29 2007 9:22pm
Subject:bk commit into 5.0 tree (aelkin:1.2490) BUG#22725
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of elkin. When elkin does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-03-29 22:22:20+03:00, aelkin@stripped
+3 -0
  Bug #22725 Replication outages from ER_SERVER_SHUTDOWN (1053) set in replication events
  
  The reason for the bug was that replaying of a query on slave could not be possible
since its event
  was recorded with the killed error.
  
  The solution treats queries on ta and non-ta tables differently. For ta-table the query
rolls back if got
  killed because there is no guarantee that a fuction the query might invoke performed its
work completely;
  otherwise, partial result can not be repeated on slave.
  Non-ta-table query is binlogged without the KILLED error if killing happened but the
INSERT did not exectute
  any stored routine, i.e it practically completed its work.
  For the INSERT that called a stored routine  binlogging is pessimistical since the query
might be performed
  partially and it's safer to stop on slave.

  mysql-test/r/kill.result@stripped, 2007-03-29 22:22:18+03:00,
aelkin@stripped +45 -0
    changed

  mysql-test/t/kill.test@stripped, 2007-03-29 22:22:18+03:00,
aelkin@stripped +66 -0
    regression tests for the bug

  sql/sql_insert.cc@stripped, 2007-03-29 22:22:18+03:00,
aelkin@stripped +33 -4
    rollback killed query if ta-table or mask-out the flag while the query event is
created.
    thd->killed is restored w/o loss of possible changing during event's create.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	aelkin
# Host:	dsl-hkibras1-ff1dc300-249.dhcp.inet.fi
# Root:	/home/elkin/MySQL/MAIN/mysql-5.0-marvel

--- 1.225/sql/sql_insert.cc	2007-03-19 23:39:47 +02:00
+++ 1.226/sql/sql_insert.cc	2007-03-29 22:22:18 +03:00
@@ -725,10 +725,39 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
         {
           if (error <= 0)
             thd->clear_error();
-          Query_log_event qinfo(thd, thd->query, thd->query_length,
-                                transactional_table, FALSE);
-          if (mysql_bin_log.write(&qinfo) && transactional_table)
-            error=1;
+          if (transactional_table && thd->killed != THD::NOT_KILLED)
+          {
+            error= 1;
+          }
+          else
+          {
+            /* bug#22725: 
+               INSERT on non-ta table that has not called stored routines
+               performes it work completely even though the query might
+               got killed. Consequently, such query can not be binlogged 
+               with `killed' error, the flag is masked out
+               for constructing binlog event.
+               killed INSERT on ta-tables not logged and rolled back;
+
+               todo: to avoid asyncronization of `error' and
+               `error_code' of binlog event constructor change the
+               constructor to accept `error_code' as an argument that
+               would be evaluated with consulting thd->killed flag and
+               thd->binlog_evt_union.unioned_events just after while-row-loop
+               completion.
+               Applies to most mysql_$query functions.
+            */
+            THD::killed_state old_killed= thd->killed;
+            if (thd->killed != THD::NOT_KILLED &&
+                thd->binlog_evt_union.unioned_events != TRUE)
+              thd->killed= THD::NOT_KILLED;
+            Query_log_event qinfo(thd, thd->query, thd->query_length,
+                                  transactional_table, FALSE);
+            if (thd->killed == THD::NOT_KILLED)
+              thd->killed= old_killed;
+            if (mysql_bin_log.write(&qinfo) && transactional_table)
+              error=1;
+          }
         }
         if (!transactional_table)
           thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;

--- 1.16/mysql-test/r/kill.result	2006-10-04 14:09:34 +03:00
+++ 1.17/mysql-test/r/kill.result	2007-03-29 22:22:18 +03:00
@@ -41,3 +41,48 @@ select 1;
 select RELEASE_LOCK("a");
 RELEASE_LOCK("a")
 1
+create function bug22725() 
+RETURNS int(11)
+DETERMINISTIC
+begin
+set @a= get_lock("a", 10);
+return 1;
+end|
+create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
+affected rows: 0
+create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM;
+affected rows: 0
+reset master;
+select get_lock("a", 20);
+get_lock("a", 20)
+1
+insert into t1 values (bug22725(),1);
+kill query 3;
+ERROR 70100: Query execution was interrupted
+show binlog events from 98 /* nothing in binlog */;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+select count(*) from t1 /* must be zero */;
+count(*)
+0
+begin;
+insert into t1 values (bug22725(),1);
+kill query 3;
+ERROR 70100: Query execution was interrupted
+select count(*) from t1 /* must be zero */;
+count(*)
+0
+commit;
+insert into t2 values (bug22725(),1);
+kill query 3;
+select count(*) from t2 /* must be one */;
+count(*)
+1
+show binlog events from 98 /* must have the insert */;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	98	Intvar	1	126	INSERT_ID=1
+master-bin.000001	126	Query	1	225	use `test`; insert into t2 values (bug22725(),1)
+select RELEASE_LOCK("a");
+RELEASE_LOCK("a")
+1
+drop table t1,t2;
+drop function bug22725;

--- 1.24/mysql-test/t/kill.test	2006-12-08 18:09:39 +02:00
+++ 1.25/mysql-test/t/kill.test	2007-03-29 22:22:18 +03:00
@@ -117,3 +117,69 @@ reap;
 select 1;
 connection con1;
 select RELEASE_LOCK("a");
+
+delimiter |;
+create function bug22725() 
+RETURNS int(11)
+DETERMINISTIC
+begin
+  set @a= get_lock("a", 10);
+  return 1;
+end|
+delimiter ;|
+
+--enable_info
+create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM;
+--disable_info
+reset master;
+
+# ta table case: killing cause rollback
+# a - autocommit ON
+connection con1;
+select get_lock("a", 20);
+
+connection con2;
+let $ID= `select connection_id()`;
+send insert into t1 values (bug22725(),1);
+
+connection con1;
+eval kill query $ID;
+
+connection con2;
+--error ER_QUERY_INTERRUPTED
+reap;
+show binlog events from 98 /* nothing in binlog */;
+select count(*) from t1 /* must be zero */;
+
+# b - multi-statement-ta
+connection con2;
+begin;
+send insert into t1 values (bug22725(),1);
+
+connection con1;
+eval kill query $ID;
+
+connection con2;
+--error ER_QUERY_INTERRUPTED
+reap;
+select count(*) from t1 /* must be zero */;
+commit;
+
+# non-ta table case: killing is ineffective
+connection con2;
+send insert into t2 values (bug22725(),1);
+
+connection con1;
+eval kill query $ID;
+
+connection con2;
+reap;
+select count(*) from t2 /* must be one */;
+show binlog events from 98 /* must have the insert */;
+
+connection con1;
+select RELEASE_LOCK("a");
+
+drop table t1,t2;
+drop function bug22725;
Thread
bk commit into 5.0 tree (aelkin:1.2490) BUG#22725Andrei Elkin29 Mar