From: Date: March 29 2007 9:22pm Subject: bk commit into 5.0 tree (aelkin:1.2490) BUG#22725 List-Archive: http://lists.mysql.com/commits/23363 X-Bug: 22725 Message-Id: <200703291922.l2TJMTKk032412@dsl-hkibras1-ff1dc300-249.dhcp.inet.fi> 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;