diff options
author | unknown <mkindahl@dl145h.mysql.com> | 2008-01-31 17:46:50 +0100 |
---|---|---|
committer | unknown <mkindahl@dl145h.mysql.com> | 2008-01-31 17:46:50 +0100 |
commit | a36faa7edaec89c22a5d449a927bf9c11f2fbfde (patch) | |
tree | c327f90b44e25f92a820d5886ba6220cf6d9c2c8 /sql/log.cc | |
parent | 4bacd53715ac860c6ba2d9c148f87d22cae9c62a (diff) | |
parent | 681bf14ea7a6fedb55d6e59a414d876d4d5f7313 (diff) | |
download | mariadb-git-a36faa7edaec89c22a5d449a927bf9c11f2fbfde.tar.gz |
Merge dl145h.mysql.com:/data0/mkindahl/mysql-5.1
into dl145h.mysql.com:/data0/mkindahl/mysql-5.1-rpl-merge
client/client_priv.h:
Auto merged
include/my_sys.h:
Auto merged
mysql-test/mysql-test-run.pl:
Auto merged
mysql-test/lib/mtr_report.pl:
Auto merged
mysql-test/suite/rpl/t/rpl_err_ignoredtable.test:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/set_var.h:
Auto merged
sql/slave.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
sql/sql_view.cc:
Auto merged
mysql-test/suite/rpl/r/rpl_invoked_features.result:
Manual merge.
mysql-test/suite/rpl/t/rpl_invoked_features.test:
Manual merge.
sql/log.cc:
Manual merge.
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 102 |
1 files changed, 76 insertions, 26 deletions
diff --git a/sql/log.cc b/sql/log.cc index 3a09acd8fca..fce1eb076db 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1420,6 +1420,21 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all) return 0; } +/** + This function is called once after each statement. + + It has the responsibility to flush the transaction cache to the + binlog file on commits. + + @param hton The binlog handlerton. + @param thd The client thread that executes the transaction. + @param all true if this is the last statement before a COMMIT + statement; false if either this is a statement in a + transaction but not the last, or if this is a statement + not inside a BEGIN block and autocommit is on. + + @see handlerton::commit +*/ static int binlog_commit(handlerton *hton, THD *thd, bool all) { DBUG_ENTER("binlog_commit"); @@ -1432,7 +1447,15 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) trx_data->reset(); DBUG_RETURN(0); } - if (all) + /* + Write commit event if at least one of the following holds: + - the user sends an explicit COMMIT; or + - the autocommit flag is on, and we are not inside a BEGIN. + However, if the user has not sent an explicit COMMIT, and we are + either inside a BEGIN or run with autocommit off, then this is not + the end of a transaction and we should not write a commit event. + */ + if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE); qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) @@ -1446,6 +1469,23 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) } } +/** + This function is called when a transaction involving a transactional + table is rolled back. + + It has the responsibility to flush the transaction cache to the + binlog file. However, if the transaction does not involve + non-transactional tables, nothing needs to be logged. + + @param hton The binlog handlerton. + @param thd The client thread that executes the transaction. + @param all true if this is the last statement before a COMMIT + statement; false if either this is a statement in a + transaction but not the last, or if this is a statement + not inside a BEGIN block and autocommit is on. + + @see handlerton::rollback +*/ static int binlog_rollback(handlerton *hton, THD *thd, bool all) { DBUG_ENTER("binlog_rollback"); @@ -4010,32 +4050,42 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) if (my_b_tell(cache) > 0) { /* - Log "BEGIN" at the beginning of the transaction. - which may contain more than 1 SQL statement. + Log "BEGIN" at the beginning of every transaction. Here, a + transaction is either a BEGIN..COMMIT block or a single + statement in autocommit mode. */ - if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) - { - Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE); - /* - Imagine this is rollback due to net timeout, after all statements of - the transaction succeeded. Then we want a zero-error code in BEGIN. - In other words, if there was a really serious error code it's already - in the statement's events, there is no need to put it also in this - internally generated event, and as this event is generated late it - would lead to false alarms. - This is safer than thd->clear_error() against kills at shutdown. - */ - qinfo.error_code= 0; - /* - Now this Query_log_event has artificial log_pos 0. It must be adjusted - to reflect the real position in the log. Not doing it would confuse the - slave: it would prevent this one from knowing where he is in the - master's binlog, which would result in wrong positions being shown to - the user, MASTER_POS_WAIT undue waiting etc. - */ - if (qinfo.write(&log_file)) - goto err; - } + Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE); + /* + Imagine this is rollback due to net timeout, after all + statements of the transaction succeeded. Then we want a + zero-error code in BEGIN. In other words, if there was a + really serious error code it's already in the statement's + events, there is no need to put it also in this internally + generated event, and as this event is generated late it would + lead to false alarms. + + This is safer than thd->clear_error() against kills at shutdown. + */ + qinfo.error_code= 0; + /* + Now this Query_log_event has artificial log_pos 0. It must be + adjusted to reflect the real position in the log. Not doing it + would confuse the slave: it would prevent this one from + knowing where he is in the master's binlog, which would result + in wrong positions being shown to the user, MASTER_POS_WAIT + undue waiting etc. + */ + if (qinfo.write(&log_file)) + goto err; + + DBUG_EXECUTE_IF("crash_before_writing_xid", + { + if ((write_error= write_cache(cache, false, true))) + DBUG_PRINT("info", ("error writing binlog cache: %d", + write_error)); + DBUG_PRINT("info", ("crashing before writing xid")); + abort(); + }); if ((write_error= write_cache(cache, false, false))) goto err; |