MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:February 4 2010 8:15pm
Subject:bzr commit into mysql-5.5-next-mr branch (kostja:3076) Bug#37148
View as plain text  
#At file:///opt/local/work/next-4284-merge/ based on revid:kostja@stripped

 3076 Konstantin Osipov	2010-02-04
      Merge next-mr -> next-4284.
      Cherry-pick a fix Bug#37148 from next-mr, to preserve
      file ids of the added files, and ensure that all the necessary
      changes have been pulled.
      
      Since initially Bug#37148 was null-merged into 6.0,
      the changeset that is now being cherry-picked was likewise
      null merged into next-4284.
      
      Now that Bug#37148 has been reapplied to 6.0, try to make
      it work with next-4284. This is also necessary to be able
      to pull other changes from 5.1-rep into next-4284.
      
      To resolve the merge issues use this changeset applied
      to 6.0:
      revid:jperkin@stripped
      revno: 3776.1.1
      committer: He Zhenxing <zhenxing.he@stripped>
      branch nick: 6.0-codebase-bugfixing
      timestamp: Thu 2009-12-17 17:02:50 +0800
      message:
        Fix merge problem with Bug#37148

    added:
      mysql-test/include/binlog_inject_error.inc
      mysql-test/suite/binlog/r/binlog_write_error.result
      mysql-test/suite/binlog/t/binlog_write_error.test
    modified:
      sql/events.cc
      sql/log.cc
      sql/log_event.cc
      sql/log_event_old.cc
      sql/mysql_priv.h
      sql/rpl_injector.cc
      sql/sp.cc
      sql/sp_head.cc
      sql/sql_acl.cc
      sql/sql_base.cc
      sql/sql_class.h
      sql/sql_db.cc
      sql/sql_delete.cc
      sql/sql_insert.cc
      sql/sql_load.cc
      sql/sql_parse.cc
      sql/sql_partition.cc
      sql/sql_rename.cc
      sql/sql_repl.cc
      sql/sql_table.cc
      sql/sql_tablespace.cc
      sql/sql_trigger.cc
      sql/sql_udf.cc
      sql/sql_update.cc
      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	2010-02-04 20:15:47 +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	2010-02-04 20:15:47 +0000
@@ -0,0 +1,108 @@
+#
+# 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;
+DROP FUNCTION IF EXISTS f1;
+DROP PROCEDURE IF EXISTS p1;
+DROP TRIGGER IF EXISTS tr1;
+DROP VIEW IF EXISTS v1, 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	2010-02-04 20:15:47 +0000
@@ -0,0 +1,101 @@
+#
+# === Name ===
+#
+# binlog_write_error.test
+#
+# === Description ===
+#
+# This test case check if the error of writing binlog file is properly
+# reported and handled 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 #
+
+disable_warnings;
+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;
+enable_warnings;

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2010-02-03 13:43:03 +0000
+++ b/sql/events.cc	2010-02-04 20:15:47 +0000
@@ -370,7 +370,7 @@ Events::create_event(THD *thd, Event_par
       }
       /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER 
          will be written into the binary log as the definer for the SQL thread. */
-      write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
+      ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
     }
   }
   mysql_mutex_unlock(&LOCK_event_metadata);
@@ -482,7 +482,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());
     }
   }
   mysql_mutex_unlock(&LOCK_event_metadata);
@@ -542,7 +542,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());
   }
   mysql_mutex_unlock(&LOCK_event_metadata);
   DBUG_RETURN(ret);

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-02-04 17:34:15 +0000
+++ b/sql/log.cc	2010-02-04 20:15:47 +0000
@@ -1495,7 +1495,7 @@ binlog_end_trans(THD *thd, binlog_trx_da
     if (all || !thd->in_multi_stmt_transaction())
     {
       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
@@ -4809,7 +4809,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *
   Incident_log_event ev(thd, incident, write_error_msg);
   if (lock)
     mysql_mutex_lock(&LOCK_log);
-  ev.write(&log_file);
+  error= ev.write(&log_file);
   if (lock)
   {
     if (!error && !(error= flush_and_sync(0)))

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-02-03 15:10:56 +0000
+++ b/sql/log_event.cc	2010-02-04 20:15:47 +0000
@@ -5877,7 +5877,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 */
@@ -7611,7 +7611,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
@@ -7622,7 +7622,7 @@ static int rows_event_stmt_cleanup(Relay
       are involved, commit the transaction and flush the pending event to the
       binlog.
     */
-    error= trans_commit_stmt(thd);
+    error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
 
     /*
       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	2010-02-03 00:06:42 +0000
+++ b/sql/log_event_old.cc	2010-02-04 20:15:47 +0000
@@ -1504,7 +1504,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, NULL);
 
@@ -1785,7 +1793,7 @@ int Old_rows_log_event::do_apply_event(R
       (assume the last master's transaction is ignored by the slave because of
       replicate-ignore rules).
     */
-    thd->binlog_flush_pending_rows_event(true);
+    int binlog_error= thd->binlog_flush_pending_rows_event(true);
 
     /*
       If this event is not in a transaction, the call below will, if some
@@ -1796,12 +1804,13 @@ int Old_rows_log_event::do_apply_event(R
       are involved, commit the transaction and flush the pending event to the
       binlog.
     */
-    if ((error= trans_commit_stmt(thd)))
+    if ((error= (binlog_error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd))))
       rli->report(ERROR_LEVEL, error,
                   "Error in %s event: commit of row events failed, "
                   "table `%s`.`%s`",
                   get_type_str(), m_table->s->db.str,
                   m_table->s->table_name.str);
+    error|= binlog_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	2010-02-04 17:34:15 +0000
+++ b/sql/mysql_priv.h	2010-02-04 20:15:47 +0000
@@ -1029,8 +1029,8 @@ struct Query_cache_query_flags
 #define query_cache_is_cacheable_query(L) 0
 #endif /*HAVE_QUERY_CACHE*/
 
-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	2009-12-22 16:09:15 +0000
+++ b/sql/rpl_injector.cc	2010-02-04 20:15:47 +0000
@@ -59,10 +59,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
@@ -88,7 +92,7 @@ int injector::transaction::commit()
      close_thread_tables(m_thd);
      m_thd->mdl_context.release_transactional_locks();
    }
-   DBUG_RETURN(0);
+   DBUG_RETURN(error);
 }
 
 
@@ -115,16 +119,16 @@ 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);
 }
 
 
@@ -134,15 +138,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);
 }
 
 
@@ -152,15 +157,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	2010-02-03 21:48:40 +0000
+++ b/sql/sp.cc	2010-02-04 20:15:47 +0000
@@ -1127,9 +1127,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;
     }
   }
@@ -1192,7 +1193,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();
 
     /*
@@ -1306,7 +1308,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();
   }
 err:

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2010-02-04 17:34:15 +0000
+++ b/sql/sp_head.cc	2010-02-04 20:15:47 +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	2010-02-03 13:43:03 +0000
+++ b/sql/sql_acl.cc	2010-02-04 20:15:47 +0000
@@ -1632,8 +1632,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);
@@ -3252,7 +3252,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());
   }
 
   mysql_rwlock_unlock(&LOCK_grant);
@@ -3419,7 +3419,8 @@ bool mysql_routine_grant(THD *thd, TABLE
 
   if (write_to_binlog)
   {
-    write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+    if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+      result= TRUE;
   }
 
   mysql_rwlock_unlock(&LOCK_grant);
@@ -3539,7 +3540,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());
   }
 
   mysql_rwlock_unlock(&LOCK_grant);
@@ -5804,7 +5805,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());
 
   mysql_rwlock_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -5877,7 +5878,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());
 
   mysql_rwlock_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -5962,7 +5963,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());
 
   mysql_rwlock_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -6144,15 +6145,17 @@ bool mysql_revoke_all(THD *thd,  List <L
 
   mysql_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());
 
   mysql_rwlock_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	2010-02-03 21:48:40 +0000
+++ b/sql/sql_base.cc	2010-02-04 20:15:47 +0000
@@ -1505,7 +1505,7 @@ 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);
+    (void)thd->binlog_flush_pending_rows_event(TRUE);
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
   }
@@ -1710,7 +1710,11 @@ void close_temporary_tables(THD *thd)
       qinfo.db= db.ptr();
       qinfo.db_len= db.length();
       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
@@ -3633,9 +3637,13 @@ static bool open_table_entry_fini(THD *t
         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));
+          return TRUE;
+        }
         my_free(query, MYF(0));
       }
       else

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-02-03 13:43:03 +0000
+++ b/sql/sql_class.h	2010-02-04 20:15:47 +0000
@@ -2892,7 +2892,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	2010-02-02 09:22:17 +0000
+++ b/sql/sql_db.cc	2010-02-04 20:15:47 +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);
 }  
 
 
@@ -774,7 +774,11 @@ not_silent:
       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);
   }
@@ -851,7 +855,8 @@ bool mysql_alter_db(THD *thd, const char
     qinfo.db_len = strlen(db);
 
     /* 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);
 
@@ -997,7 +1002,11 @@ bool mysql_rm_db(THD *thd,char *db,bool 
       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;
+      }
     }
     thd->clear_error();
     thd->server_status|= SERVER_STATUS_DB_DROPPED;
@@ -1025,7 +1034,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;
       }
 
@@ -1038,7 +1051,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;
+      }
     }
   }
 
@@ -1994,7 +2011,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	2010-02-03 00:06:42 +0000
+++ b/sql/sql_delete.cc	2010-02-04 20:15:47 +0000
@@ -851,9 +851,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;
   }
@@ -1254,8 +1255,9 @@ end:
     {
       /* In RBR, the statement is not binlogged if the table is temporary. */
       if (!is_temporary_table || !thd->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
     }
     if (has_mdl_lock)
       thd->mdl_context.release_transactional_locks();

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-02-04 17:34:15 +0000
+++ b/sql/sql_insert.cc	2010-02-04 20:15:47 +0000
@@ -2828,10 +2828,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;
     }
@@ -2905,8 +2906,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
@@ -3360,16 +3362,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,
+    if (thd->binlog_query(THD::ROW_QUERY_TYPE,
                       thd->query(), thd->query_length(),
-                      trans_table, FALSE, errcode);
+                      trans_table, FALSE, errcode))
+    {
+      table->file->ha_release_auto_increment();
+      DBUG_RETURN(1);
+    }
   }
   table->file->ha_release_auto_increment();
 
@@ -3440,9 +3447,10 @@ 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;
@@ -3712,7 +3720,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;
     }
@@ -3819,7 +3828,7 @@ select_create::prepare(List<Item> &value
   DBUG_RETURN(0);
 }
 
-void
+int
 select_create::binlog_show_create_table(TABLE **tables, uint count)
 {
   /*
@@ -3858,12 +3867,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)
@@ -3961,7 +3971,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	2010-02-03 13:43:03 +0000
+++ b/sql/sql_load.cc	2010-02-04 20:15:47 +0000
@@ -155,7 +155,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;
@@ -543,18 +543,20 @@ 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, ex,
-                                               table_list->db, 
-                                               table_list->table_name,
-                                               handle_duplicates, ignore,
-                                               transactional_table,
-                                               errcode);
+            (void) write_execute_load_query_log_event(thd, ex,
+                                                      table_list->db, 
+                                                      table_list->table_name,
+                                                      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);
 	  }
 	}
       }
@@ -581,7 +583,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
     {
       /*
@@ -593,13 +595,15 @@ 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, ex,
-                                           table_list->db, table_list->table_name,
-                                           handle_duplicates, ignore,
-                                           transactional_table,
-                                           errcode);
+        error= write_execute_load_query_log_event(thd, ex,
+                                                  table_list->db, table_list->table_name,
+                                                  handle_duplicates, ignore,
+                                                  transactional_table,
+                                                  errcode);
       }
     }
+    if (error)
+      goto err;
   }
 #endif /*!EMBEDDED_LIBRARY*/
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-02-04 17:34:15 +0000
+++ b/sql/sql_parse.cc	2010-02-04 20:15:47 +0000
@@ -2766,7 +2766,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;
@@ -2798,7 +2798,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;
@@ -2821,7 +2821,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;
@@ -2950,7 +2950,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()"));
@@ -3753,7 +3753,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);
     } 
@@ -4221,12 +4222,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	2010-02-03 13:43:03 +0000
+++ b/sql/sql_partition.cc	2010-02-04 20:15:47 +0000
@@ -4377,8 +4377,9 @@ static int fast_end_partition(THD *thd, 
     DBUG_RETURN(TRUE);                      /* The error has been reported */
 
   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	2010-02-01 23:22:16 +0000
+++ b/sql/sql_rename.cc	2010-02-04 20:15:47 +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};
@@ -176,11 +177,11 @@ bool mysql_rename_tables(THD *thd, TABLE
   */
   mysql_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:
   thd->global_read_lock.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	2010-02-04 17:34:15 +0000
+++ b/sql/sql_repl.cc	2010-02-04 20:15:47 +0000
@@ -1213,8 +1213,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);
@@ -1951,7 +1951,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)
 {
@@ -1978,7 +1979,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
     {
@@ -1986,7 +1988,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	2010-02-04 13:06:29 +0000
+++ b/sql/sql_table.cc	2010-02-04 20:15:47 +0000
@@ -1742,9 +1742,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;
@@ -1752,9 +1753,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;
 }
 
 
@@ -2143,7 +2145,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 &&
                tmp_table_deleted)
@@ -2165,7 +2167,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());
         }
 
         /*
@@ -2184,7 +2186,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
           */
           built_tmp_query.chop();                  // Chop of the last comma
           built_tmp_query.append(" /* generated by server */");
-          write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
+          error|= write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
         }
       }
 
@@ -3660,9 +3662,9 @@ void sp_prepare_create_field(THD *thd, C
   RETURN VALUES
     NONE
  */
-static inline void write_create_table_bin_log(THD *thd,
-                                              const HA_CREATE_INFO *create_info,
-                                              bool internal_tmp_table)
+static inline int write_create_table_bin_log(THD *thd,
+                                             const HA_CREATE_INFO *create_info,
+                                             bool internal_tmp_table)
 {
   /*
     Don't write statement if:
@@ -3675,7 +3677,8 @@ static inline void write_create_table_bi
       (!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());
+    return write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+  return 0;
 }
 
 
@@ -3944,8 +3947,7 @@ bool mysql_create_table_no_lock(THD *thd
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                           ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
                           alias);
-      error= 0;
-      write_create_table_bin_log(thd, create_info, internal_tmp_table);
+      error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
       goto err;
     }
     my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
@@ -4094,7 +4096,7 @@ bool mysql_create_table_no_lock(THD *thd
     thd->thread_specific_used= TRUE;
   }
 
-  error= FALSE;
+  error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
 unlock_and_end:
   mysql_mutex_unlock(&LOCK_open);
 
@@ -4109,7 +4111,7 @@ warn:
                       ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
                       alias);
   create_info->table_existed= 1;		// Mark that table existed
-  write_create_table_bin_log(thd, create_info, internal_tmp_table);
+  error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
   goto unlock_and_end;
 }
 
@@ -4172,7 +4174,7 @@ bool mysql_create_table(THD *thd, TABLE_
       (!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());
+    result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
   if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
   {
@@ -5285,7 +5287,8 @@ 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;
 
         DBUG_ASSERT(thd->open_tables == table->table);
         mysql_mutex_lock(&LOCK_open);
@@ -5298,14 +5301,15 @@ bool mysql_create_like_table(THD* thd, T
         mysql_mutex_unlock(&LOCK_open);
       }
       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;
 
 err:
   DBUG_RETURN(res);
@@ -5385,7 +5389,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:
   trans_rollback_stmt(thd);
@@ -6440,12 +6444,14 @@ 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);
     }
     mysql_mutex_unlock(&LOCK_open);
 
+view_err_unlock:
     unlock_table_names(thd);
 
 view_err:
@@ -6715,8 +6721,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)
     {
@@ -7225,8 +7232,9 @@ view_err:
     if (rename_temporary_table(thd, new_table, new_db, new_name))
       goto err_new_table_cleanup;
     /* 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;
   }
 
@@ -7390,7 +7398,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	2009-12-16 08:15:40 +0000
+++ b/sql/sql_tablespace.cc	2010-02-04 20:15:47 +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	2010-02-03 21:48:40 +0000
+++ b/sql/sql_trigger.cc	2010-02-04 20:15:47 +0000
@@ -511,7 +511,7 @@ bool mysql_create_or_drop_trigger(THD *t
 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());
   }
 
   /*

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2010-02-03 13:43:03 +0000
+++ b/sql/sql_udf.cc	2010-02-04 20:15:47 +0000
@@ -524,8 +524,8 @@ int mysql_create_function(THD *thd,udf_f
   mysql_rwlock_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:
@@ -599,8 +599,8 @@ int mysql_drop_function(THD *thd,const L
     Binlog the drop function. Keep the table open and locked
     while binlogging, to avoid binlog inconsistency.
   */
-  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:
   mysql_rwlock_unlock(&THR_LOCK_udf);

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2010-02-03 13:43:03 +0000
+++ b/sql/sql_update.cc	2010-02-04 20:15:47 +0000
@@ -1874,9 +1874,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	2010-02-03 21:48:40 +0000
+++ b/sql/sql_view.cc	2010-02-04 20:15:47 +0000
@@ -659,8 +659,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;
   }
 
   mysql_mutex_unlock(&LOCK_open);
@@ -1681,7 +1682,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;
   }
 
   mysql_mutex_unlock(&LOCK_open);


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100204201547-p0mot6yk0kpn93rp.bundle
Thread
bzr commit into mysql-5.5-next-mr branch (kostja:3076) Bug#37148Konstantin Osipov4 Feb