MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:September 30 2009 1:49am
Subject:bzr commit into mysql-5.1-bugteam branch (zhenxing.he:2973) Bug#37148
View as plain text  
#At file:///media/sdb2/hezx/work/mysql/bzrwork/b37148/5.1-bugteam/ based on revid:aelkin@stripped

 2973 He Zhenxing	2009-09-30
      BUG#37148 Most callers of mysql_bin_log.write ignore the return result
      
      The return value of mysql_bin_log.write was ignored by most callers,
      which may lead to inconsistent on master and slave if the transaction
      was committed while the binlog was not correctly written.
      
      This fixed the problem by let the caller to check and handle the
      return value of mysql_bin_log.write. This patch only adresses the
      simple cases.
     @ mysql-test/include/binlog_inject_error.inc
        inject binlog write error when doing a query
     @ mysql-test/suite/binlog/t/binlog_write_error.test
        Simple test case to check if proper error is reported when injecting binlog write errors.

    A  mysql-test/include/binlog_inject_error.inc
    A  mysql-test/suite/binlog/r/binlog_write_error.result
    A  mysql-test/suite/binlog/t/binlog_write_error.test
    M  sql/events.cc
    M  sql/ha_ndbcluster_binlog.cc
    M  sql/log.cc
    M  sql/log_event.cc
    M  sql/log_event_old.cc
    M  sql/mysql_priv.h
    M  sql/rpl_injector.cc
    M  sql/sp.cc
    M  sql/sp_head.cc
    M  sql/sql_acl.cc
    M  sql/sql_base.cc
    M  sql/sql_class.h
    M  sql/sql_db.cc
    M  sql/sql_delete.cc
    M  sql/sql_insert.cc
    M  sql/sql_load.cc
    M  sql/sql_parse.cc
    M  sql/sql_partition.cc
    M  sql/sql_rename.cc
    M  sql/sql_repl.cc
    M  sql/sql_table.cc
    M  sql/sql_tablespace.cc
    M  sql/sql_trigger.cc
    M  sql/sql_udf.cc
    M  sql/sql_update.cc
    M  sql/sql_view.cc
=== added file 'mysql-test/include/binlog_inject_error.inc'
--- a/mysql-test/include/binlog_inject_error.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/binlog_inject_error.inc	2009-09-30 01:48:50 +0000
@@ -0,0 +1,22 @@
+#
+# === Name
+#
+# binlog_inject_error.inc
+#
+# === Description
+#
+# Inject binlog write error when running the query, verifies that the
+# query is ended with the proper error (ER_ERROR_ON_WRITE).
+#
+# === Usage
+#
+# let query= 'CREATE TABLE t1 (a INT)';
+# source include/binlog_inject_error.inc;
+#
+
+SET GLOBAL debug='d,injecting_fault_writing';
+--echo $query;
+--replace_regex /(errno: .*)/(errno: #)/
+--error ER_ERROR_ON_WRITE
+--eval $query
+SET GLOBAL debug='';

=== added file 'mysql-test/suite/binlog/r/binlog_write_error.result'
--- a/mysql-test/suite/binlog/r/binlog_write_error.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/r/binlog_write_error.result	2009-09-30 01:48:50 +0000
@@ -0,0 +1,120 @@
+#
+# Initialization
+#
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TRIGGER IF EXISTS tr1;
+DROP TRIGGER IF EXISTS tr2;
+DROP VIEW IF EXISTS v1, v2;
+#
+# Test injecting binlog write error when executing queries
+#
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE TABLE t1 (a INT);
+CREATE TABLE t1 (a INT);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+INSERT INTO t1 VALUES (1),(2),(3);
+SET GLOBAL debug='d,injecting_fault_writing';
+INSERT INTO t1 VALUES (4),(5),(6);
+INSERT INTO t1 VALUES (4),(5),(6);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+UPDATE t1 set a=a+1;
+UPDATE t1 set a=a+1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DELETE FROM t1;
+DELETE FROM t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
+CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP TRIGGER tr1;
+DROP TRIGGER tr1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+ALTER TABLE t1 ADD (b INT);
+ALTER TABLE t1 ADD (b INT);
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE VIEW v1 AS SELECT a FROM t1;
+CREATE VIEW v1 AS SELECT a FROM t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP VIEW v1;
+DROP VIEW v1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
+CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP PROCEDURE p1;
+DROP PROCEDURE p1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP TABLE t1;
+DROP TABLE t1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE FUNCTION f1() RETURNS INT return 1;
+CREATE FUNCTION f1() RETURNS INT return 1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP FUNCTION f1;
+DROP FUNCTION f1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+CREATE USER user1;
+CREATE USER user1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+SET GLOBAL debug='d,injecting_fault_writing';
+DROP USER user1;
+DROP USER user1;
+ERROR HY000: Error writing file 'master-bin' ((errno: #)
+SET GLOBAL debug='';
+#
+# Cleanup
+#
+DROP TABLE IF EXISTS t1, t2;
+Warnings:
+Note	1051	Unknown table 't1'
+Note	1051	Unknown table 't2'
+DROP FUNCTION IF EXISTS f1;
+Warnings:
+Note	1305	FUNCTION f1 does not exist
+DROP PROCEDURE IF EXISTS p1;
+Warnings:
+Note	1305	PROCEDURE p1 does not exist
+DROP TRIGGER IF EXISTS tr1;
+Warnings:
+Note	1360	Trigger does not exist
+DROP VIEW IF EXISTS v1, v2;
+Warnings:
+Note	1051	Unknown table 'test.v1'
+Note	1051	Unknown table 'test.v2'

=== added file 'mysql-test/suite/binlog/t/binlog_write_error.test'
--- a/mysql-test/suite/binlog/t/binlog_write_error.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_write_error.test	2009-09-30 01:48:50 +0000
@@ -0,0 +1,99 @@
+#
+# === Name ===
+#
+# binlog_write_error.test
+#
+# === Description ===
+#
+# This test case check if the error of writing binlog file is proper
+# reported and handle when executing statements.
+#
+# === Related Bugs ===
+#
+# BUG#37148
+#
+
+source include/have_log_bin.inc;
+source include/have_debug.inc;
+
+--echo #
+--echo # Initialization
+--echo #
+
+disable_warnings;
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TRIGGER IF EXISTS tr1;
+DROP TRIGGER IF EXISTS tr2;
+DROP VIEW IF EXISTS v1, v2;
+enable_warnings;
+
+--echo #
+--echo # Test injecting binlog write error when executing queries
+--echo #
+
+let $query= CREATE TABLE t1 (a INT);
+source include/binlog_inject_error.inc;
+
+INSERT INTO t1 VALUES (1),(2),(3);
+
+let $query= INSERT INTO t1 VALUES (4),(5),(6);
+source include/binlog_inject_error.inc;
+
+let $query= UPDATE t1 set a=a+1;
+source include/binlog_inject_error.inc;
+
+let $query= DELETE FROM t1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100);
+source include/binlog_inject_error.inc;
+
+let $query= DROP TRIGGER tr1;
+source include/binlog_inject_error.inc;
+
+let $query= ALTER TABLE t1 ADD (b INT);
+source include/binlog_inject_error.inc;
+
+let $query= CREATE VIEW v1 AS SELECT a FROM t1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP VIEW v1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP PROCEDURE p1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP TABLE t1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE FUNCTION f1() RETURNS INT return 1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP FUNCTION f1;
+source include/binlog_inject_error.inc;
+
+let $query= CREATE USER user1;
+source include/binlog_inject_error.inc;
+
+let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1;
+source include/binlog_inject_error.inc;
+
+let $query= DROP USER user1;
+source include/binlog_inject_error.inc;
+
+--echo #
+--echo # Cleanup
+--echo #
+
+DROP TABLE IF EXISTS t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP PROCEDURE IF EXISTS p1;
+DROP TRIGGER IF EXISTS tr1;
+DROP VIEW IF EXISTS v1, v2;

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2009-04-09 06:22:06 +0000
+++ b/sql/events.cc	2009-09-30 01:48:50 +0000
@@ -439,7 +439,7 @@ Events::create_event(THD *thd, Event_par
     {
       /* Binlog the create event. */
       DBUG_ASSERT(thd->query && thd->query_length);
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      ret= write_bin_log(thd, TRUE, thd->query, thd->query_length);
     }
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
@@ -560,7 +560,7 @@ Events::update_event(THD *thd, Event_par
                                   new_element);
       /* Binlog the alter event. */
       DBUG_ASSERT(thd->query && thd->query_length);
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      ret= write_bin_log(thd, TRUE, thd->query, thd->query_length);
     }
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
@@ -635,7 +635,7 @@ Events::drop_event(THD *thd, LEX_STRING 
       event_queue->drop_event(thd, dbname, name);
     /* Binlog the drop event. */
     DBUG_ASSERT(thd->query && thd->query_length);
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    ret= write_bin_log(thd, TRUE, thd->query, thd->query_length);
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
   DBUG_RETURN(ret);

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2009-06-19 08:24:43 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2009-09-30 01:48:50 +0000
@@ -1837,7 +1837,7 @@ ndb_handle_schema_change(THD *thd, Ndb *
   DBUG_RETURN(0);
 }
 
-static void ndb_binlog_query(THD *thd, Cluster_schema *schema)
+static int ndb_binlog_query(THD *thd, Cluster_schema *schema)
 {
   if (schema->any_value & NDB_ANYVALUE_RESERVED)
   {
@@ -1845,7 +1845,7 @@ static void ndb_binlog_query(THD *thd, C
       sql_print_warning("NDB: unknown value for binlog signalling 0x%X, "
                         "query not logged",
                         schema->any_value);
-    return;
+    return 0;
   }
   uint32 thd_server_id_save= thd->server_id;
   DBUG_ASSERT(sizeof(thd_server_id_save) == sizeof(thd->server_id));
@@ -1856,12 +1856,13 @@ static void ndb_binlog_query(THD *thd, C
     thd->server_id= schema->any_value;
   thd->db= schema->db;
   int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
-  thd->binlog_query(THD::STMT_QUERY_TYPE, schema->query,
-                    schema->query_length, FALSE,
-                    schema->name[0] == 0 || thd->db[0] == 0,
-                    errcode);
+  int error= thd->binlog_query(THD::STMT_QUERY_TYPE, schema->query,
+                               schema->query_length, FALSE,
+                               schema->name[0] == 0 || thd->db[0] == 0,
+                               errcode);
   thd->server_id= thd_server_id_save;
   thd->db= thd_db_save;
+  return error;
 }
 
 static int
@@ -2029,8 +2030,9 @@ ndb_binlog_thread_handle_schema_event(TH
         case SOT_CLEAR_SLOCK:
           abort();
         }
-        if (log_query && ndb_binlog_running)
-          ndb_binlog_query(thd, schema);
+        if (log_query && ndb_binlog_running &&
+            ndb_binlog_query(thd, schema))
+          DBUG_RETURN(1);
         /* signal that schema operation has been handled */
         DBUG_DUMP("slock", (uchar*) schema->slock, schema->slock_length);
         if (bitmap_is_set(&slock, node_id))
@@ -2152,7 +2154,7 @@ ndb_binlog_thread_handle_schema_event(TH
   process any operations that should be done after
   the epoch is complete
 */
-static void
+static int
 ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
                                                  List<Cluster_schema>
                                                  *post_epoch_log_list,
@@ -2160,7 +2162,7 @@ ndb_binlog_thread_handle_schema_event_po
                                                  *post_epoch_unlock_list)
 {
   if (post_epoch_log_list->elements == 0)
-    return;
+    return 0;
   DBUG_ENTER("ndb_binlog_thread_handle_schema_event_post_epoch");
   Cluster_schema *schema;
   while ((schema= post_epoch_log_list->pop()))
@@ -2288,14 +2290,15 @@ ndb_binlog_thread_handle_schema_event_po
         share= 0;
       }
     }
-    if (ndb_binlog_running && log_query)
-      ndb_binlog_query(thd, schema);
+    if (ndb_binlog_running && log_query &&
+        ndb_binlog_query(thd, schema))
+      DBUG_RETURN(1);
   }
   while ((schema= post_epoch_unlock_list->pop()))
   {
     ndbcluster_update_slock(thd, schema->db, schema->name);
   }
-  DBUG_VOID_RETURN;
+  DBUG_RETURN(0);
 }
 
 /*
@@ -3469,9 +3472,10 @@ ndb_binlog_thread_handle_data_event(Ndb 
           since table has a primary key, we can do a write
           using only after values
         */
-        trans.write_row(originating_server_id,
-                        injector::transaction::table(table, TRUE),
-                        &b, n_fields, table->record[0]);// after values
+        IF_DBUG(int ret=) trans.write_row(originating_server_id,
+                                          injector::transaction::table(table, TRUE),
+                                          &b, n_fields, table->record[0]);// after values
+        DBUG_ASSERT(ret == 0);
       }
       else
       {
@@ -3993,10 +3997,11 @@ restart:
       {
         if (!pOp->hasError())
         {
-          ndb_binlog_thread_handle_schema_event(thd, s_ndb, pOp,
-                                                &post_epoch_log_list,
-                                                &post_epoch_unlock_list,
-                                                &mem_root);
+          if (ndb_binlog_thread_handle_schema_event(thd, s_ndb, pOp,
+                                                    &post_epoch_log_list,
+                                                    &post_epoch_unlock_list,
+                                                    &mem_root))
+            goto err;
           DBUG_PRINT("info", ("s_ndb first: %s", s_ndb->getEventOperation() ?
                               s_ndb->getEventOperation()->getEvent()->getTable()->getName() :
                               "<empty>"));
@@ -4137,11 +4142,12 @@ restart:
             table->field[2]->store("", 0, &my_charset_bin);
             table->field[3]->store((longlong)0);
             table->field[4]->store((longlong)0);
-            trans.write_row(::server_id,
-                            injector::transaction::table(table, TRUE),
-                            &table->s->all_set, table->s->fields,
-                            table->record[0]);
-          }
+            IF_DBUG(int ret=) trans.write_row(::server_id,
+                                              injector::transaction::table(table, TRUE),
+                                              &table->s->all_set, table->s->fields,
+                                              table->record[0]);
+            DBUG_ASSERT(ret == 0);
+        }
           else
           {
             sql_print_error("NDB: Could not get apply status share");
@@ -4268,9 +4274,10 @@ restart:
       }
     }
 
-    ndb_binlog_thread_handle_schema_event_post_epoch(thd,
-                                                     &post_epoch_log_list,
-                                                     &post_epoch_unlock_list);
+    if (ndb_binlog_thread_handle_schema_event_post_epoch(thd,
+                                                         &post_epoch_log_list,
+                                                         &post_epoch_unlock_list))
+      goto err;
     free_root(&mem_root, MYF(0));
     *root_ptr= old_root;
     ndb_latest_handled_binlog_epoch= ndb_latest_received_binlog_epoch;

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-06-19 08:24:43 +0000
+++ b/sql/log.cc	2009-09-30 01:48:50 +0000
@@ -1446,7 +1446,7 @@ binlog_end_trans(THD *thd, binlog_trx_da
     if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
     {
       if (trx_data->has_incident())
-        mysql_bin_log.write_incident(thd, TRUE);
+        error= mysql_bin_log.write_incident(thd, TRUE);
       trx_data->reset();
     }
     else                                        // ...statement
@@ -4433,7 +4433,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *
   Incident_log_event ev(thd, incident, write_error_msg);
   if (lock)
     pthread_mutex_lock(&LOCK_log);
-  ev.write(&log_file);
+  error= ev.write(&log_file);
   if (lock)
   {
     if (!error && !(error= flush_and_sync()))

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2009-06-18 17:58:56 +0000
+++ b/sql/log_event.cc	2009-09-30 01:48:50 +0000
@@ -5784,7 +5784,7 @@ Slave_log_event::Slave_log_event(const c
 int Slave_log_event::do_apply_event(Relay_log_info const *rli)
 {
   if (mysql_bin_log.is_open())
-    mysql_bin_log.write(this);
+    return mysql_bin_log.write(this);
   return 0;
 }
 #endif /* !MYSQL_CLIENT */
@@ -7522,7 +7522,7 @@ static int rows_event_stmt_cleanup(Relay
       (assume the last master's transaction is ignored by the slave because of
       replicate-ignore rules).
     */
-    thd->binlog_flush_pending_rows_event(true);
+    error= thd->binlog_flush_pending_rows_event(true);
 
     /*
       If this event is not in a transaction, the call below will, if some
@@ -7533,7 +7533,7 @@ static int rows_event_stmt_cleanup(Relay
       are involved, commit the transaction and flush the pending event to the
       binlog.
     */
-    error= ha_autocommit_or_rollback(thd, 0);
+    error|= ha_autocommit_or_rollback(thd, error);
 
     /*
       Now what if this is not a transactional engine? we still need to

=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc	2009-02-13 16:41:47 +0000
+++ b/sql/log_event_old.cc	2009-09-30 01:48:50 +0000
@@ -1541,7 +1541,15 @@ int Old_rows_log_event::do_apply_event(R
         NOTE: For this new scheme there should be no pending event:
         need to add code to assert that is the case.
        */
-      thd->binlog_flush_pending_rows_event(false);
+      error= thd->binlog_flush_pending_rows_event(false);
+      if (error)
+      {
+        rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+                    ER(ER_SLAVE_FATAL_ERROR),
+                    "call to binlog_flush_pending_rows_event() failed");
+        thd->is_slave_error= 1;
+        DBUG_RETURN(error);
+      }
       TABLE_LIST *tables= rli->tables_to_lock;
       close_tables_for_reopen(thd, &tables);
 
@@ -1858,7 +1866,7 @@ Old_rows_log_event::do_update_pos(Relay_
       (assume the last master's transaction is ignored by the slave because of
       replicate-ignore rules).
     */
-    thd->binlog_flush_pending_rows_event(true);
+    error= thd->binlog_flush_pending_rows_event(true);
 
     /*
       If this event is not in a transaction, the call below will, if some
@@ -1869,7 +1877,7 @@ Old_rows_log_event::do_update_pos(Relay_
       are involved, commit the transaction and flush the pending event to the
       binlog.
     */
-    error= ha_autocommit_or_rollback(thd, 0);
+    error|= ha_autocommit_or_rollback(thd, error);
 
     /*
       Now what if this is not a transactional engine? we still need to

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-06-05 11:23:58 +0000
+++ b/sql/mysql_priv.h	2009-09-30 01:48:50 +0000
@@ -1025,8 +1025,8 @@ check_and_unset_inject_value(int value)
 
 #endif
 
-void write_bin_log(THD *thd, bool clear_error,
-                   char const *query, ulong query_length);
+int write_bin_log(THD *thd, bool clear_error,
+                  char const *query, ulong query_length);
 
 /* sql_connect.cc */
 int check_user(THD *thd, enum enum_server_command command, 

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2008-02-19 11:43:01 +0000
+++ b/sql/rpl_injector.cc	2009-09-30 01:48:50 +0000
@@ -58,10 +58,14 @@ injector::transaction::~transaction()
   my_free(the_memory, MYF(0));
 }
 
+/**
+   @retval 0 transaction committed
+   @retval 1 transaction rolled back
+ */
 int injector::transaction::commit()
 {
    DBUG_ENTER("injector::transaction::commit()");
-   m_thd->binlog_flush_pending_rows_event(true);
+   int error= m_thd->binlog_flush_pending_rows_event(true);
    /*
      Cluster replication does not preserve statement or
      transaction boundaries of the master.  Instead, a new
@@ -81,9 +85,9 @@ int injector::transaction::commit()
      is committed by committing the statement transaction
      explicitly.
    */
-   ha_autocommit_or_rollback(m_thd, 0);
-   end_trans(m_thd, COMMIT);
-   DBUG_RETURN(0);
+   error |= ha_autocommit_or_rollback(m_thd, error);
+   end_trans(m_thd, error ? ROLLBACK : COMMIT);
+   DBUG_RETURN(error);
 }
 
 int injector::transaction::use_table(server_id_type sid, table tbl)
@@ -109,16 +113,17 @@ int injector::transaction::write_row (se
 				      record_type record)
 {
    DBUG_ENTER("injector::transaction::write_row(...)");
-
-   if (int error= check_state(ROW_STATE))
+ 
+   int error= 0;
+   if (error= check_state(ROW_STATE))
      DBUG_RETURN(error);
 
    server_id_type save_id= m_thd->server_id;
    m_thd->set_server_id(sid);
-   m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(), 
-                           cols, colcnt, record);
+   error= m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(), 
+                                  cols, colcnt, record);
    m_thd->set_server_id(save_id);
-   DBUG_RETURN(0);
+   DBUG_RETURN(error);
 }
 
 
@@ -128,15 +133,16 @@ int injector::transaction::delete_row(se
 {
    DBUG_ENTER("injector::transaction::delete_row(...)");
 
-   if (int error= check_state(ROW_STATE))
+   int error= 0;
+   if (error= check_state(ROW_STATE))
      DBUG_RETURN(error);
 
    server_id_type save_id= m_thd->server_id;
    m_thd->set_server_id(sid);
-   m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(), 
-                            cols, colcnt, record);
+   error= m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(), 
+                                   cols, colcnt, record);
    m_thd->set_server_id(save_id);
-   DBUG_RETURN(0);
+   DBUG_RETURN(error);
 }
 
 
@@ -146,15 +152,16 @@ int injector::transaction::update_row(se
 {
    DBUG_ENTER("injector::transaction::update_row(...)");
 
-   if (int error= check_state(ROW_STATE))
+   int error= 0;
+   if (error= check_state(ROW_STATE))
      DBUG_RETURN(error);
 
    server_id_type save_id= m_thd->server_id;
    m_thd->set_server_id(sid);
-   m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(),
-		            cols, colcnt, before, after);
+   error= m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(),
+                                   cols, colcnt, before, after);
    m_thd->set_server_id(save_id);
-   DBUG_RETURN(0);
+   DBUG_RETURN(error);
 }
 
 

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2009-05-30 13:32:28 +0000
+++ b/sql/sp.cc	2009-09-30 01:48:50 +0000
@@ -939,9 +939,10 @@ sp_create_routine(THD *thd, int type, sp
       /* restore sql_mode when binloging */
       thd->variables.sql_mode= saved_mode;
       /* Such a statement can always go directly to binlog, no trans cache */
-      thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                        log_query.c_ptr(), log_query.length(),
-                        FALSE, FALSE, 0);
+      if (thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                            log_query.c_ptr(), log_query.length(),
+                            FALSE, FALSE, 0))
+        ret= SP_INTERNAL_ERROR;
       thd->variables.sql_mode= 0;
     }
 
@@ -1000,7 +1001,8 @@ sp_drop_routine(THD *thd, int type, sp_n
 
   if (ret == SP_OK)
   {
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+      ret= SP_INTERNAL_ERROR;
     sp_cache_invalidate();
   }
 
@@ -1070,7 +1072,8 @@ sp_update_routine(THD *thd, int type, sp
 
   if (ret == SP_OK)
   {
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+      ret= SP_INTERNAL_ERROR;
     sp_cache_invalidate();
   }
 

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2009-05-30 13:32:28 +0000
+++ b/sql/sp_head.cc	2009-09-30 01:48:50 +0000
@@ -1788,6 +1788,7 @@ sp_head::execute_function(THD *thd, Item
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
                      "Invoked ROUTINE modified a transactional table but MySQL "
                      "failed to reflect this change in the binary log");
+        err_status= TRUE;
       }
       reset_dynamic(&thd->user_var_events);
       /* Forget those values, in case more function calls are binlogged: */

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_acl.cc	2009-09-30 01:48:50 +0000
@@ -1654,8 +1654,8 @@ bool change_password(THD *thd, const cha
                   acl_user->host.hostname ? acl_user->host.hostname : "",
                   new_password));
     thd->clear_error();
-    thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
-                      FALSE, FALSE, 0);
+    result= thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
+                              FALSE, FALSE, 0);
   }
 end:
   close_thread_tables(thd);
@@ -3184,7 +3184,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
 
   if (!result) /* success */
   {
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    result= write_bin_log(thd, TRUE, thd->query, thd->query_length);
   }
 
   rw_unlock(&LOCK_grant);
@@ -3349,7 +3349,8 @@ bool mysql_routine_grant(THD *thd, TABLE
 
   if (write_to_binlog)
   {
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+      result= TRUE;
   }
 
   rw_unlock(&LOCK_grant);
@@ -3461,7 +3462,7 @@ bool mysql_grant(THD *thd, const char *d
 
   if (!result)
   {
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    result= write_bin_log(thd, TRUE, thd->query, thd->query_length);
   }
 
   rw_unlock(&LOCK_grant);
@@ -5664,7 +5665,7 @@ bool mysql_create_user(THD *thd, List <L
     my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
 
   if (some_users_created)
-    write_bin_log(thd, FALSE, thd->query, thd->query_length);
+    result |= write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -5737,7 +5738,7 @@ bool mysql_drop_user(THD *thd, List <LEX
     my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
 
   if (some_users_deleted)
-    write_bin_log(thd, FALSE, thd->query, thd->query_length);
+    result |= write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -5822,7 +5823,7 @@ bool mysql_rename_user(THD *thd, List <L
     my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
   
   if (some_users_renamed && mysql_bin_log.is_open())
-    write_bin_log(thd, FALSE, thd->query, thd->query_length);
+    result |= write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -6004,15 +6005,17 @@ bool mysql_revoke_all(THD *thd,  List <L
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
 
-  write_bin_log(thd, FALSE, thd->query, thd->query_length);
+  int binlog_error=
+    write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
 
-  if (result)
+  /* error for writing binary log has already been reported */
+  if (result && !binlog_error)
     my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
 
-  DBUG_RETURN(result);
+  DBUG_RETURN(result || binlog_error);
 }
 
 

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_base.cc	2009-09-30 01:48:50 +0000
@@ -1333,7 +1333,8 @@ void close_thread_tables(THD *thd)
       handled either before writing a query log event (inside
       binlog_query()) or when preparing a pending event.
      */
-    thd->binlog_flush_pending_rows_event(TRUE);
+    /* TODO: I (hezx) think the error here should not be ignored */
+    (void)thd->binlog_flush_pending_rows_event(TRUE);
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
   }
@@ -1543,7 +1544,11 @@ void close_temporary_tables(THD *thd)
                             s_query.length() - 1 /* to remove trailing ',' */,
                             0, FALSE, 0);
       thd->variables.character_set_client= cs_save;
-      mysql_bin_log.write(&qinfo);
+      if (mysql_bin_log.write(&qinfo))
+      {
+        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, MYF(0),
+                     "Failed to write the DROP statement for temporary tables to binary log");
+      }
       thd->variables.pseudo_thread_id= save_pseudo_thread_id;
     }
     else
@@ -4016,9 +4021,13 @@ retry:
         end = strxmov(strmov(query, "DELETE FROM `"),
                       share->db.str,"`.`",share->table_name.str,"`", NullS);
         int errcode= query_error_code(thd, TRUE);
-        thd->binlog_query(THD::STMT_QUERY_TYPE,
-                          query, (ulong)(end-query),
-                          FALSE, FALSE, errcode);
+        if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+                              query, (ulong)(end-query),
+                              FALSE, FALSE, errcode))
+        {
+          my_free(query, MYF(0));
+          goto err;
+        }
         my_free(query, MYF(0));
       }
       else

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-06-15 15:53:45 +0000
+++ b/sql/sql_class.h	2009-09-30 01:48:50 +0000
@@ -2564,7 +2564,7 @@ public:
     {}
   int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
 
-  void binlog_show_create_table(TABLE **tables, uint count);
+  int binlog_show_create_table(TABLE **tables, uint count);
   void store_values(List<Item> &values);
   void send_error(uint errcode,const char *err);
   bool send_eof();

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_db.cc	2009-09-30 01:48:50 +0000
@@ -178,13 +178,13 @@ uchar* dboptions_get_key(my_dbopt_t *opt
   Helper function to write a query to binlog used by mysql_rm_db()
 */
 
-static inline void write_to_binlog(THD *thd, char *query, uint q_len,
-                                   char *db, uint db_len)
+static inline int write_to_binlog(THD *thd, char *query, uint q_len,
+                                  char *db, uint db_len)
 {
   Query_log_event qinfo(thd, query, q_len, 0, 0, 0);
   qinfo.db= db;
   qinfo.db_len= db_len;
-  mysql_bin_log.write(&qinfo);
+  return mysql_bin_log.write(&qinfo);
 }  
 
 
@@ -747,7 +747,11 @@ int mysql_create_db(THD *thd, char *db, 
       qinfo.db_len = strlen(db);
 
       /* These DDL methods and logging protected with LOCK_mysql_create_db */
-      mysql_bin_log.write(&qinfo);
+      if (mysql_bin_log.write(&qinfo))
+      {
+        error= -1;
+        goto exit;
+      }
     }
     my_ok(thd, result);
   }
@@ -825,7 +829,8 @@ bool mysql_alter_db(THD *thd, const char
 
     thd->clear_error();
     /* These DDL methods and logging protected with LOCK_mysql_create_db */
-    mysql_bin_log.write(&qinfo);
+    if (error= mysql_bin_log.write(&qinfo))
+      goto exit;
   }
   my_ok(thd, result);
 
@@ -972,7 +977,11 @@ bool mysql_rm_db(THD *thd,char *db,bool 
 
       thd->clear_error();
       /* These DDL methods and logging protected with LOCK_mysql_create_db */
-      mysql_bin_log.write(&qinfo);
+      if (mysql_bin_log.write(&qinfo))
+      {
+        error= -1;
+        goto exit;
+      }
     }
     thd->clear_error();
     thd->server_status|= SERVER_STATUS_DB_DROPPED;
@@ -1000,7 +1009,11 @@ bool mysql_rm_db(THD *thd,char *db,bool 
       if (query_pos + tbl_name_len + 1 >= query_end)
       {
         /* These DDL methods and logging protected with LOCK_mysql_create_db */
-        write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
+        if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
+        {
+          error= -1;
+          goto exit;
+        }
         query_pos= query_data_start;
       }
 
@@ -1013,7 +1026,11 @@ bool mysql_rm_db(THD *thd,char *db,bool 
     if (query_pos != query_data_start)
     {
       /* These DDL methods and logging protected with LOCK_mysql_create_db */
-      write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
+      if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
+      {
+        error= -1;
+        goto exit;
+      }
     }
   }
 
@@ -1964,7 +1981,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRI
     Query_log_event qinfo(thd, thd->query, thd->query_length,
                           0, TRUE, errcode);
     thd->clear_error();
-    mysql_bin_log.write(&qinfo);
+    error|= mysql_bin_log.write(&qinfo);
   }
 
   /* Step9: Let's do "use newdb" if we renamed the current database */

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_delete.cc	2009-09-30 01:48:50 +0000
@@ -841,9 +841,10 @@ void multi_delete::abort()
     if (mysql_bin_log.is_open())
     {
       int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
-      thd->binlog_query(THD::ROW_QUERY_TYPE,
-                        thd->query, thd->query_length,
-                        transactional_tables, FALSE, errcode);
+      /* possible error of writing binary log is ignored deliberately */
+      (void) thd->binlog_query(THD::ROW_QUERY_TYPE,
+                               thd->query, thd->query_length,
+                               transactional_tables, FALSE, errcode);
     }
     thd->transaction.all.modified_non_trans_table= true;
   }
@@ -1128,8 +1129,9 @@ end:
         TRUNCATE must always be statement-based binlogged (not row-based) so
         we don't test current_stmt_binlog_row_based.
       */
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
-      my_ok(thd);		// This should return record count
+      error= write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      if (!error)
+        my_ok(thd);		// This should return record count
     }
     VOID(pthread_mutex_lock(&LOCK_open));
     unlock_table_name(thd, table_list);

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-06-22 14:01:42 +0000
+++ b/sql/sql_insert.cc	2009-09-30 01:48:50 +0000
@@ -2683,10 +2683,11 @@ bool Delayed_insert::handle_inserts(void
         will be binlogged together as one single Table_map event and one
         single Rows event.
       */
-      thd.binlog_query(THD::ROW_QUERY_TYPE,
-                       row->query.str, row->query.length,
-                       FALSE, FALSE, errcode);
-
+      if (thd.binlog_query(THD::ROW_QUERY_TYPE,
+                           row->query.str, row->query.length,
+                           FALSE, FALSE, errcode))
+        goto err;
+      
       thd.time_zone_used = backup_time_zone_used;
       thd.variables.time_zone = backup_time_zone;
     }
@@ -2754,8 +2755,9 @@ bool Delayed_insert::handle_inserts(void
 
     TODO: Move the logging to last in the sequence of rows.
    */
-  if (thd.current_stmt_binlog_row_based)
-    thd.binlog_flush_pending_rows_event(TRUE);
+  if (thd.current_stmt_binlog_row_based &&
+      thd.binlog_flush_pending_rows_event(TRUE))
+    goto err;
 
   if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
   {						// This shouldn't happen
@@ -3207,16 +3209,21 @@ bool select_insert::send_eof()
     events are in the transaction cache and will be written when
     ha_autocommit_or_rollback() is issued below.
   */
-  if (mysql_bin_log.is_open())
+  if (mysql_bin_log.is_open() &&
+      (!error || thd->transaction.stmt.modified_non_trans_table))
   {
     int errcode= 0;
     if (!error)
       thd->clear_error();
     else
       errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
-    thd->binlog_query(THD::ROW_QUERY_TYPE,
-                      thd->query, thd->query_length,
-                      trans_table, FALSE, errcode);
+    if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+                          thd->query, thd->query_length,
+                          trans_table, FALSE, errcode))
+    {
+      table->file->ha_release_auto_increment();
+      DBUG_RETURN(1);
+    }
   }
   table->file->ha_release_auto_increment();
 
@@ -3285,8 +3292,9 @@ void select_insert::abort() {
         if (mysql_bin_log.is_open())
         {
           int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
-          thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
-                            transactional_table, FALSE, errcode);
+          /* error of writing binary log is ignored */
+          (void)thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
+                                  transactional_table, FALSE, errcode);
         }
         if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
           thd->transaction.all.modified_non_trans_table= TRUE;
@@ -3560,7 +3568,8 @@ select_create::prepare(List<Item> &value
           !table->s->tmp_table &&
           !ptr->get_create_info()->table_existed)
       {
-        ptr->binlog_show_create_table(tables, count);
+        if (int error= ptr->binlog_show_create_table(tables, count))
+          return error;
       }
       return 0;
     }
@@ -3642,7 +3651,7 @@ select_create::prepare(List<Item> &value
   DBUG_RETURN(0);
 }
 
-void
+int
 select_create::binlog_show_create_table(TABLE **tables, uint count)
 {
   /*
@@ -3681,12 +3690,13 @@ select_create::binlog_show_create_table(
   if (mysql_bin_log.is_open())
   {
     int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
-    thd->binlog_query(THD::STMT_QUERY_TYPE,
-                      query.ptr(), query.length(),
-                      /* is_trans */ TRUE,
-                      /* suppress_use */ FALSE,
-                      errcode);
+    result= thd->binlog_query(THD::STMT_QUERY_TYPE,
+                              query.ptr(), query.length(),
+                              /* is_trans */ TRUE,
+                              /* suppress_use */ FALSE,
+                              errcode);
   }
+  return result;
 }
 
 void select_create::store_values(List<Item> &values)
@@ -3784,7 +3794,8 @@ void select_create::abort()
   select_insert::abort();
   thd->transaction.stmt.modified_non_trans_table= FALSE;
   reenable_binlog(thd);
-  thd->binlog_flush_pending_rows_event(TRUE);
+  /* possible error of writing binary log is ignored deliberately */
+  (void)thd->binlog_flush_pending_rows_event(TRUE);
 
   if (m_plock)
   {

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2009-06-17 14:56:44 +0000
+++ b/sql/sql_load.cc	2009-09-30 01:48:50 +0000
@@ -119,7 +119,7 @@ int mysql_load(THD *thd,sql_exchange *ex
   char name[FN_REFLEN];
   File file;
   TABLE *table= NULL;
-  int error;
+  int error= 0;
   String *field_term=ex->field_term,*escaped=ex->escaped;
   String *enclosed=ex->enclosed;
   bool is_fifo=0;
@@ -485,15 +485,17 @@ int mysql_load(THD *thd,sql_exchange *ex
 	{
           int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
           
+          /* since there is already an error, the possible error of
+             writing binary log will be ignored */
 	  if (thd->transaction.stmt.modified_non_trans_table)
-	    write_execute_load_query_log_event(thd, handle_duplicates,
-					       ignore, transactional_table,
-                                               errcode);
+	    (void) write_execute_load_query_log_event(thd, handle_duplicates,
+                                                      ignore, transactional_table,
+                                                      errcode);
 	  else
 	  {
 	    Delete_file_log_event d(thd, db, transactional_table);
             d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
-	    mysql_bin_log.write(&d);
+	    (void) mysql_bin_log.write(&d);
 	  }
 	}
       }
@@ -519,7 +521,7 @@ int mysql_load(THD *thd,sql_exchange *ex
       after this point.
      */
     if (thd->current_stmt_binlog_row_based)
-      thd->binlog_flush_pending_rows_event(true);
+      error= thd->binlog_flush_pending_rows_event(true);
     else
     {
       /*
@@ -531,10 +533,12 @@ int mysql_load(THD *thd,sql_exchange *ex
       if (lf_info.wrote_create_file)
       {
         int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
-        write_execute_load_query_log_event(thd, handle_duplicates, ignore,
-                                           transactional_table, errcode);
+        error= write_execute_load_query_log_event(thd, handle_duplicates, ignore,
+                                                  transactional_table, errcode);
       }
     }
+    if (error)
+      goto err;
   }
 #endif /*!EMBEDDED_LIBRARY*/
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-06-17 14:56:44 +0000
+++ b/sql/sql_parse.cc	2009-09-30 01:48:50 +0000
@@ -2945,7 +2945,7 @@ end_with_restore_list:
       /*
         Presumably, REPAIR and binlog writing doesn't require synchronization
       */
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      res= write_bin_log(thd, TRUE, thd->query, thd->query_length);
     }
     select_lex->table_list.first= (uchar*) first_table;
     lex->query_tables=all_tables;
@@ -2977,7 +2977,7 @@ end_with_restore_list:
       /*
         Presumably, ANALYZE and binlog writing doesn't require synchronization
       */
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      res= write_bin_log(thd, TRUE, thd->query, thd->query_length);
     }
     select_lex->table_list.first= (uchar*) first_table;
     lex->query_tables=all_tables;
@@ -3000,7 +3000,7 @@ end_with_restore_list:
       /*
         Presumably, OPTIMIZE and binlog writing doesn't require synchronization
       */
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      res= write_bin_log(thd, TRUE, thd->query, thd->query_length);
     }
     select_lex->table_list.first= (uchar*) first_table;
     lex->query_tables=all_tables;
@@ -3117,7 +3117,7 @@ end_with_restore_list:
       if (incident)
       {
         Incident_log_event ev(thd, incident);
-        mysql_bin_log.write(&ev);
+        (void) mysql_bin_log.write(&ev);        /* error is ignored */
         mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
       }
       DBUG_PRINT("debug", ("Just after generate_incident()"));
@@ -3952,7 +3952,8 @@ end_with_restore_list:
       */
       if (!lex->no_write_to_binlog && write_to_binlog)
       {
-        write_bin_log(thd, FALSE, thd->query, thd->query_length);
+        if (res= write_bin_log(thd, FALSE, thd->query, thd->query_length))
+          break;
       }
       my_ok(thd);
     } 
@@ -4529,12 +4530,12 @@ create_sp_error:
       case SP_KEY_NOT_FOUND:
 	if (lex->drop_if_exists)
 	{
-          write_bin_log(thd, TRUE, thd->query, thd->query_length);
+          res= write_bin_log(thd, TRUE, thd->query, thd->query_length);
 	  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 			      ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
 			      SP_COM_STRING(lex), lex->spname->m_name.str);
-	  res= FALSE;
-	  my_ok(thd);
+          if (!res)
+            my_ok(thd);
 	  break;
 	}
 	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_partition.cc	2009-09-30 01:48:50 +0000
@@ -4027,8 +4027,9 @@ static int fast_end_partition(THD *thd, 
   }
 
   if ((!is_empty) && (!written_bin_log) &&
-      (!thd->lex->no_write_to_binlog))
-    write_bin_log(thd, FALSE, thd->query, thd->query_length);
+      (!thd->lex->no_write_to_binlog) &&
+      write_bin_log(thd, FALSE, thd->query, thd->query_length))
+    DBUG_RETURN(TRUE);
 
   my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
               (ulong) (copied + deleted),

=== modified file 'sql/sql_rename.cc'
--- a/sql/sql_rename.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_rename.cc	2009-09-30 01:48:50 +0000
@@ -34,6 +34,7 @@ static TABLE_LIST *reverse_table_list(TA
 bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
 {
   bool error= 1;
+  bool binlog_error= 0;
   TABLE_LIST *ren_table= 0;
   int to_table;
   char *rename_log_table[2]= {NULL, NULL};
@@ -174,11 +175,11 @@ bool mysql_rename_tables(THD *thd, TABLE
   */
   pthread_mutex_unlock(&LOCK_open);
 
-  /* Lets hope this doesn't fail as the result will be messy */ 
   if (!silent && !error)
   {
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
-    my_ok(thd);
+    binlog_error= write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    if (!binlog_error)
+      my_ok(thd);
   }
 
   if (!error)
@@ -190,7 +191,7 @@ bool mysql_rename_tables(THD *thd, TABLE
 
 err:
   start_waiting_global_read_lock(thd);
-  DBUG_RETURN(error);
+  DBUG_RETURN(error || binlog_error);
 }
 
 

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2009-05-15 12:57:51 +0000
+++ b/sql/sql_repl.cc	2009-09-30 01:48:50 +0000
@@ -1007,8 +1007,8 @@ int reset_slave(THD *thd, Master_info* m
   MY_STAT stat_area;
   char fname[FN_REFLEN];
   int thread_mask= 0, error= 0;
-  uint sql_errno=0;
-  const char* errmsg=0;
+  uint sql_errno=ER_UNKNOWN_ERROR;
+  const char* errmsg= "Unknown error occured while reseting slave";
   DBUG_ENTER("reset_slave");
 
   lock_slave_threads(mi);
@@ -1673,7 +1673,8 @@ err:
    replication events along LOAD DATA processing.
    
    @param file  pointer to io-cache
-   @return 0
+   @retval 0 success
+   @retval 1 failure
 */
 int log_loaded_block(IO_CACHE* file)
 {
@@ -1700,7 +1701,8 @@ int log_loaded_block(IO_CACHE* file)
       Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
                                min(block_len, max_event_size),
                                lf_info->log_delayed);
-      mysql_bin_log.write(&a);
+      if (mysql_bin_log.write(&a))
+        DBUG_RETURN(1);
     }
     else
     {
@@ -1708,7 +1710,8 @@ int log_loaded_block(IO_CACHE* file)
                                    buffer,
                                    min(block_len, max_event_size),
                                    lf_info->log_delayed);
-      mysql_bin_log.write(&b);
+      if (mysql_bin_log.write(&b))
+        DBUG_RETURN(1);
       lf_info->wrote_create_file= 1;
       DBUG_SYNC_POINT("debug_lock.created_file_event",10);
     }

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_table.cc	2009-09-30 01:48:50 +0000
@@ -1683,9 +1683,10 @@ end:
     file
 */
 
-void write_bin_log(THD *thd, bool clear_error,
-                   char const *query, ulong query_length)
+int write_bin_log(THD *thd, bool clear_error,
+                  char const *query, ulong query_length)
 {
+  int error= 0;
   if (mysql_bin_log.is_open())
   {
     int errcode= 0;
@@ -1693,9 +1694,10 @@ void write_bin_log(THD *thd, bool clear_
       thd->clear_error();
     else
       errcode= query_error_code(thd, TRUE);
-    thd->binlog_query(THD::STMT_QUERY_TYPE,
-                      query, query_length, FALSE, FALSE, errcode);
+    error= thd->binlog_query(THD::STMT_QUERY_TYPE,
+                             query, query_length, FALSE, FALSE, errcode);
   }
+  return error;
 }
 
 
@@ -2020,7 +2022,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
           tables).  In this case, we can write the original query into
           the binary log.
          */
-        write_bin_log(thd, !error, thd->query, thd->query_length);
+        error |= write_bin_log(thd, !error, thd->query, thd->query_length);
       }
       else if (thd->current_stmt_binlog_row_based &&
                non_temp_tables_count > 0 &&
@@ -2040,7 +2042,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
         */
         built_query.chop();                  // Chop of the last comma
         built_query.append(" /* generated by server */");
-        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
+        error |= write_bin_log(thd, !error, built_query.ptr(), built_query.length());
       }
       /*
         The remaining cases are:
@@ -3815,6 +3817,7 @@ bool mysql_create_table_no_lock(THD *thd
     thd->thread_specific_used= TRUE;
   }
 
+  error= FALSE;
   /*
     Don't write statement if:
     - It is an internal temporary table,
@@ -3826,8 +3829,7 @@ bool mysql_create_table_no_lock(THD *thd
       (!thd->current_stmt_binlog_row_based ||
        (thd->current_stmt_binlog_row_based &&
         !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
-  error= FALSE;
+    error= write_bin_log(thd, TRUE, thd->query, thd->query_length);
 unlock_and_end:
   VOID(pthread_mutex_unlock(&LOCK_open));
 
@@ -5283,17 +5285,19 @@ bool mysql_create_like_table(THD* thd, T
                             create_info, FALSE /* show_database */);
 
         DBUG_ASSERT(result == 0); // store_create_info() always return 0
-        write_bin_log(thd, TRUE, query.ptr(), query.length());
+        if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
+          goto err;
       }
       else                                      // Case 1
-        write_bin_log(thd, TRUE, thd->query, thd->query_length);
+        if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+          goto err;
     }
     /*
       Case 3 and 4 does nothing under RBR
     */
   }
-  else
-    write_bin_log(thd, TRUE, thd->query, thd->query_length);
+  else if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+    goto err;
 
   res= FALSE;
   goto err;
@@ -5395,7 +5399,7 @@ mysql_discard_or_import_tablespace(THD *
     error=1;
   if (error)
     goto err;
-  write_bin_log(thd, FALSE, thd->query, thd->query_length);
+  error= write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
 err:
   ha_autocommit_or_rollback(thd, error);
@@ -6408,11 +6412,13 @@ bool mysql_alter_table(THD *thd,char *ne
         thd->clear_error();
         Query_log_event qinfo(thd, thd->query, thd->query_length,
                               0, FALSE, 0);
-        mysql_bin_log.write(&qinfo);
+        if (error= mysql_bin_log.write(&qinfo))
+          goto view_err_unlock;
       }
       my_ok(thd);
     }
 
+view_err_unlock:
     unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
 
 view_err:
@@ -6650,8 +6656,9 @@ view_err:
 
     if (!error)
     {
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
-      my_ok(thd);
+      error= write_bin_log(thd, TRUE, thd->query, thd->query_length);
+      if (!error)
+        my_ok(thd);
     }
     else if (error > 0)
     {
@@ -7139,8 +7146,9 @@ view_err:
     if (rename_temporary_table(thd, new_table, new_db, new_name))
       goto err1;
     /* We don't replicate alter table statement on temporary tables */
-    if (!thd->current_stmt_binlog_row_based)
-      write_bin_log(thd, TRUE, thd->query, thd->query_length);
+    if (!thd->current_stmt_binlog_row_based &&
+        write_bin_log(thd, TRUE, thd->query, thd->query_length))
+      DBUG_RETURN(TRUE);
     goto end_temporary;
   }
 
@@ -7303,7 +7311,8 @@ view_err:
   DBUG_ASSERT(!(mysql_bin_log.is_open() &&
                 thd->current_stmt_binlog_row_based &&
                 (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
-  write_bin_log(thd, TRUE, thd->query, thd->query_length);
+  if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+    DBUG_RETURN(TRUE);
 
   if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
   {

=== modified file 'sql/sql_tablespace.cc'
--- a/sql/sql_tablespace.cc	2007-06-19 11:27:53 +0000
+++ b/sql/sql_tablespace.cc	2009-09-30 01:48:50 +0000
@@ -66,6 +66,6 @@ int mysql_alter_tablespace(THD *thd, st_
                         ha_resolve_storage_engine_name(hton),
                         "TABLESPACE or LOGFILE GROUP");
   }
-  write_bin_log(thd, FALSE, thd->query, thd->query_length);
-  DBUG_RETURN(FALSE);
+  error= write_bin_log(thd, FALSE, thd->query, thd->query_length);
+  DBUG_RETURN(error);
 }

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2009-06-17 14:56:44 +0000
+++ b/sql/sql_trigger.cc	2009-09-30 01:48:50 +0000
@@ -507,7 +507,7 @@ end:
 
   if (!result)
   {
-    write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length());
+    result= write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length());
   }
 
   VOID(pthread_mutex_unlock(&LOCK_open));

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2009-05-15 12:57:51 +0000
+++ b/sql/sql_udf.cc	2009-09-30 01:48:50 +0000
@@ -506,8 +506,8 @@ int mysql_create_function(THD *thd,udf_f
   rw_unlock(&THR_LOCK_udf);
 
   /* Binlog the create function. */
-  write_bin_log(thd, TRUE, thd->query, thd->query_length);
-
+  if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+    DBUG_RETURN(1);
   DBUG_RETURN(0);
 
  err:
@@ -581,8 +581,8 @@ int mysql_drop_function(THD *thd,const L
   rw_unlock(&THR_LOCK_udf);
 
   /* Binlog the drop function. */
-  write_bin_log(thd, TRUE, thd->query, thd->query_length);
-
+  if (write_bin_log(thd, TRUE, thd->query, thd->query_length))
+    DBUG_RETURN(1);
   DBUG_RETURN(0);
  err:
   rw_unlock(&THR_LOCK_udf);

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2009-06-18 14:16:14 +0000
+++ b/sql/sql_update.cc	2009-09-30 01:48:50 +0000
@@ -1851,9 +1851,10 @@ void multi_update::abort()
         into repl event.
       */
       int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
-      thd->binlog_query(THD::ROW_QUERY_TYPE,
-                        thd->query, thd->query_length,
-                        transactional_tables, FALSE, errcode);
+      /* the error of binary logging is ignored */
+      (void)thd->binlog_query(THD::ROW_QUERY_TYPE,
+                              thd->query, thd->query_length,
+                              transactional_tables, FALSE, errcode);
     }
     thd->transaction.all.modified_non_trans_table= TRUE;
   }

=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc	2009-06-19 08:24:43 +0000
+++ b/sql/sql_view.cc	2009-09-30 01:48:50 +0000
@@ -662,8 +662,9 @@ bool mysql_create_view(THD *thd, TABLE_L
     buff.append(views->source.str, views->source.length);
 
     int errcode= query_error_code(thd, TRUE);
-    thd->binlog_query(THD::STMT_QUERY_TYPE,
-                      buff.ptr(), buff.length(), FALSE, FALSE, errcode);
+    if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+                          buff.ptr(), buff.length(), FALSE, FALSE, errcode))
+      res= TRUE;
   }
 
   VOID(pthread_mutex_unlock(&LOCK_open));
@@ -1653,7 +1654,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
     /* if something goes wrong, bin-log with possible error code,
        otherwise bin-log with error code cleared.
      */
-    write_bin_log(thd, !something_wrong, thd->query, thd->query_length);
+    if (write_bin_log(thd, !something_wrong, thd->query, thd->query_length))
+      something_wrong= 1;
   }
 
   VOID(pthread_mutex_unlock(&LOCK_open));


Attachment: [text/bzr-bundle] bzr/zhenxing.he@sun.com-20090930014850-d7myeu3pne97iys0.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (zhenxing.he:2973) Bug#37148He Zhenxing30 Sep
  • Re: bzr commit into mysql-5.1-bugteam branch (zhenxing.he:2973)Bug#37148Andrei Elkin13 Oct