diff options
author | He Zhenxing <zhenxing.he@sun.com> | 2009-11-21 12:28:01 +0800 |
---|---|---|
committer | He Zhenxing <zhenxing.he@sun.com> | 2009-11-21 12:28:01 +0800 |
commit | dd383cadec0fbfba626bba72051f2dc548171015 (patch) | |
tree | 33edb6115f37aa26c592dd1aa99a17b195511f5e /sql/rpl_injector.cc | |
parent | 27fca0ab1775a8c1dfe699c978b6448a7aa8f47b (diff) | |
download | mariadb-git-dd383cadec0fbfba626bba72051f2dc548171015.tar.gz |
BUG#37148 Most callers of mysql_bin_log.write ignore the return result
This is the non-ndb part of the patch.
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. If
my_error() is call in mysql_bin_log.write, this could also lead to
assertion issue if my_ok() or my_error() is called after.
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.
sql/events.cc:
check return value of mysql_bin_log.write
sql/log.cc:
check return value of mysql_bin_log.write
sql/log_event.cc:
check return value of mysql_bin_log.write
sql/log_event_old.cc:
check return value of mysql_bin_log.write
sql/mysql_priv.h:
Change write_bin_log to return int instead of void
sql/rpl_injector.cc:
check return value of writing binlog
sql/sp.cc:
check return value of writing binlog
sql/sp_head.cc:
return 1 if writing binlog failed
sql/sql_acl.cc:
check return value of writing binlog
sql/sql_base.cc:
check return value of writing binlog
sql/sql_class.h:
Change binlog_show_create_table to return int
sql/sql_db.cc:
Change write_to_binlog to return int
check return value of writing binlog
sql/sql_delete.cc:
check return value of writing binlog
sql/sql_insert.cc:
check return value of writing binlog
sql/sql_load.cc:
check return value of writing binlog
sql/sql_parse.cc:
check return value of writing binlog
sql/sql_partition.cc:
check return value of writing binlog
sql/sql_rename.cc:
check return value of writing binlog
sql/sql_repl.cc:
check return value of writing binlog
sql/sql_table.cc:
Change write_bin_log to return int, and return 1 if there was error writing binlog
sql/sql_tablespace.cc:
check return value of writing binlog
sql/sql_trigger.cc:
check return value of writing binlog
sql/sql_udf.cc:
check return value of writing binlog
sql/sql_update.cc:
check return value of writing binlog
sql/sql_view.cc:
check return value of writing binlog
Diffstat (limited to 'sql/rpl_injector.cc')
-rw-r--r-- | sql/rpl_injector.cc | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index 684655d1c3b..666622dbac4 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -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 (server_id_type sid, table tbl, 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(server_id_type sid, table tbl, { 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(server_id_type sid, table tbl, { 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); } |