List:Internals« Previous MessageNext Message »
From:guilhem Date:September 20 2005 5:41pm
Subject:bk commit into 5.0 tree (guilhem:1.1990) BUG#13348
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of guilhem. When guilhem 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
  1.1990 05/09/20 17:41:47 guilhem@stripped +6 -0
  Fix fur BUG#13348: "multi-table updates and deletes are not logged if no rows were
affected".
  Not fixed in 4.1 as not critical. Also I'm correcting error checking of
multi-UPDATE/DELETE
  when it comes to binlogging, to make it consistent with when we rollback the statement.

  sql/sql_update.cc
    1.171 05/09/20 17:41:42 guilhem@stripped +14 -7
    we now binlog multi-UPDATE even if no row was updated (like we do for UPDATE).
    Adding to existing tests to test new behaviour.
    I'm also correcting some error checking (< instead of <=), basing myself on when
we rollback.

  sql/sql_delete.cc
    1.162 05/09/20 17:41:42 guilhem@stripped +8 -20
    We now binlog multi-DELETE even if no row was updated (like we do for DELETE).
    I'm also correcting some error checking (< instead of <=), basing myself on when
we rollback.

  mysql-test/t/rpl_multi_update.test
    1.9 05/09/20 17:41:42 guilhem@stripped +23 -0
    test of BUG#13348

  mysql-test/t/rpl_multi_delete.test
    1.5 05/09/20 17:41:42 guilhem@stripped +20 -4
    test for BUG#13348

  mysql-test/r/rpl_multi_update.result
    1.7 05/09/20 17:41:42 guilhem@stripped +13 -0
    result update

  mysql-test/r/rpl_multi_delete.result
    1.4 05/09/20 17:41:42 guilhem@stripped +9 -0
    result update

# 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:	guilhem
# Host:	gbichot3.local
# Root:	/home/mysql_src/mysql-5.0

--- 1.161/sql/sql_delete.cc	2005-09-01 21:42:21 +02:00
+++ 1.162/sql/sql_delete.cc	2005-09-20 17:41:42 +02:00
@@ -258,19 +258,12 @@
 
   delete select;
   transactional_table= table->file->has_transactions();
-  /*
-    We write to the binary log even if we deleted no row, because maybe the
-    user is using this command to ensure that a table is clean on master *and
-    on slave*. Think of the case of a user having played separately with the
-    master's table and slave's table and wanting to take a fresh identical
-    start now.
-    error < 0 means "really no error". error <= 0 means "maybe some error".
-  */
-  if ((deleted || (error < 0)) && (error <= 0 || !transactional_table))
+  /* See similar binlogging code in sql_update.cc, for comments */
+  if ((error < 0) || (deleted && !transactional_table))
   {
     if (mysql_bin_log.is_open())
     {
-      if (error <= 0)
+      if (error < 0)
         thd->clear_error();
       Query_log_event qinfo(thd, thd->query, thd->query_length,
 			    transactional_table, FALSE);
@@ -718,6 +711,9 @@
   /* Does deletes for the last n - 1 tables, returns 0 if ok */
   int local_error= do_deletes();		// returns 0 if success
 
+  /* compute a total error to know if something failed */
+  local_error= local_error || error;
+
   /* reset used flags */
   thd->proc_info="end";
 
@@ -730,19 +726,11 @@
     query_cache_invalidate3(thd, delete_tables, 1);
   }
 
-  /*
-    Write the SQL statement to the binlog if we deleted
-    rows and we succeeded, or also in an error case when there
-    was a non-transaction-safe table involved, since
-    modifications in it cannot be rolled back.
-    Note that if we deleted nothing we don't write to the binlog (TODO:
-    fix this).
-  */
-  if (deleted && ((error <= 0 && !local_error) || normal_tables))
+  if ((local_error == 0) || (deleted && normal_tables))
   {
     if (mysql_bin_log.is_open())
     {
-      if (error <= 0 && !local_error)
+      if (local_error == 0)
         thd->clear_error();
       Query_log_event qinfo(thd, thd->query, thd->query_length,
 			    transactional_tables, FALSE);

--- 1.170/sql/sql_update.cc	2005-09-15 01:57:52 +02:00
+++ 1.171/sql/sql_update.cc	2005-09-20 17:41:42 +02:00
@@ -475,11 +475,20 @@
     query_cache_invalidate3(thd, table_list, 1);
   }
 
-  if ((updated || (error < 0)) && (error <= 0 || !transactional_table))
+  /*
+    error < 0 means really no error at all: we processed all rows until the
+    last one without error. error > 0 means an error (e.g. unique key
+    violation and no IGNORE or REPLACE). error == 0 is also an error (if
+    preparing the record or invoking before triggers fails). See
+    ha_autocommit_or_rollback(error>=0) and DBUG_RETURN(error>=0) below.
+    Sometimes we want to binlog even if we updated no rows, in case user used
+    it to be sure master and slave are in same state.
+  */
+  if ((error < 0) || (updated && !transactional_table))
   {
     if (mysql_bin_log.is_open())
     {
-      if (error <= 0)
+      if (error < 0)
         thd->clear_error();
       Query_log_event qinfo(thd, thd->query, thd->query_length,
 			    transactional_table, FALSE);
@@ -1439,16 +1448,14 @@
   /*
     Write the SQL statement to the binlog if we updated
     rows and we succeeded or if we updated some non
-    transacational tables.
-    Note that if we updated nothing we don't write to the binlog (TODO:
-    fix this).
+    transactional tables.
   */
 
-  if (updated && (local_error <= 0 || !trans_safe))
+  if ((local_error == 0) || (updated && !trans_safe))
   {
     if (mysql_bin_log.is_open())
     {
-      if (local_error <= 0)
+      if (local_error == 0)
         thd->clear_error();
       Query_log_event qinfo(thd, thd->query, thd->query_length,
 			    transactional_tables, FALSE);

--- 1.3/mysql-test/r/rpl_multi_delete.result	2004-03-20 11:31:15 +01:00
+++ 1.4/mysql-test/r/rpl_multi_delete.result	2005-09-20 17:41:42 +02:00
@@ -19,4 +19,13 @@
 select * from t2;
 a
 1
+delete from t1;
+delete from t2;
+insert into t1 values(1);
+insert into t2 values(1);
+DELETE t1.*, t2.* from t1, t2;
+select * from t1;
+a
+select * from t2;
+a
 drop table t1,t2;

--- 1.6/mysql-test/r/rpl_multi_update.result	2005-09-15 16:18:53 +02:00
+++ 1.7/mysql-test/r/rpl_multi_update.result	2005-09-20 17:41:42 +02:00
@@ -24,3 +24,16 @@
 1	0
 2	1
 UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
+delete from t1;
+delete from t2;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+update t1 set a=2;
+UPDATE t1, t2 SET t1.a = t2.a;
+select * from t1;
+a	b
+1	1
+select * from t2;
+a	b
+1	1
+drop table t1, t2;

--- 1.4/mysql-test/t/rpl_multi_delete.test	2005-09-15 16:17:19 +02:00
+++ 1.5/mysql-test/t/rpl_multi_delete.test	2005-09-20 17:41:42 +02:00
@@ -16,10 +16,26 @@
 select * from t1;
 select * from t2;
 
+# End of 4.1 tests
+
+# Check if deleting 0 rows is binlogged (BUG#13348)
+
 connection master;
-drop table t1,t2;
-save_master_pos;
+delete from t1;
+delete from t2;
+
 connection slave;
-sync_with_master;
+# force a difference to see if master's multi-DELETE will correct it
+insert into t1 values(1);
+insert into t2 values(1);
 
-# End of 4.1 tests
+connection master;
+DELETE t1.*, t2.* from t1, t2;
+
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+connection master;
+drop table t1,t2;
+sync_slave_with_master;

--- 1.8/mysql-test/t/rpl_multi_update.test	2005-09-15 16:17:20 +02:00
+++ 1.9/mysql-test/t/rpl_multi_update.test	2005-09-20 17:41:42 +02:00
@@ -24,3 +24,26 @@
 sync_with_master;
 
 # End of 4.1 tests
+
+# Check if updating 0 rows is binlogged (BUG#13348)
+
+connection master;
+delete from t1;
+delete from t2;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+
+connection slave;
+# force a difference to see if master's multi-UPDATE will correct it
+update t1 set a=2;
+
+connection master;
+UPDATE t1, t2 SET t1.a = t2.a;
+
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+connection master;
+drop table t1, t2;
+sync_slave_with_master;
Thread
bk commit into 5.0 tree (guilhem:1.1990) BUG#13348guilhem20 Sep