Loading sql/handler.cc +31 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ int ha_autocommit_or_rollback(THD *thd, int error) } else (void) ha_rollback_stmt(thd); thd->tx_isolation=thd->session_tx_isolation; } #endif Loading Loading @@ -309,6 +310,36 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if (trans == &thd->transaction.all && mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log)) { /* We write the command "COMMIT" as the last SQL command in the binlog segment cached for this transaction */ int save_query_length = thd->query_length; thd->query_length = 6; /* length of 'COMMIT'; note that we may come here because a DROP TABLE, for instance, makes an implicit commit, and then thd->query is not 'COMMIT'! */ Query_log_event qinfo(thd, "COMMIT", TRUE); /* When we come here, and the user wrapped the transaction into BEGIN and COMMIT, then qinfo got above the field cache_stmt erroneously set to 0. Let us set it to 1: */ qinfo.cache_stmt = 1; /* Write the 'COMMIT' entry to the cache */ if (mysql_bin_log.write(&qinfo)) { my_error(ER_ERROR_DURING_COMMIT, MYF(0), 5000); error=1; } thd->query_length = save_query_length; /* Now we write the binlog segment cached for this transaction to the real binlog */ mysql_bin_log.write(thd, &thd->transaction.trans_log); reinit_io_cache(&thd->transaction.trans_log, WRITE_CACHE, (my_off_t) 0, 0, 1); Loading sql/log.cc +36 −4 Original line number Diff line number Diff line Loading @@ -442,8 +442,8 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) #ifdef HAVE_FTRUNCATE if (ftruncate(index_file,0)) { sql_print_error("Could not truncate the binlog index file \ during log purge for write"); sql_print_error( "Could not truncate the binlog index file during log purge for write"); error = LOG_INFO_FATAL; goto err; } Loading @@ -455,8 +455,8 @@ during log purge for write"); O_CREAT | O_BINARY | O_RDWR | O_APPEND, MYF(MY_WME)))) { sql_print_error("Could not re-open the binlog index file \ during log purge for write"); sql_print_error( "Could not re-open the binlog index file during log purge for write"); error = LOG_INFO_FATAL; goto err; } Loading Loading @@ -661,6 +661,38 @@ bool MYSQL_LOG::write(Query_log_event* event_info) error=1; if (file == &thd->transaction.trans_log && !my_b_tell(&thd->transaction.trans_log)) { /* Add the "BEGIN" and "COMMIT" in the binlog around transactions which may contain more than 1 SQL statement. If we run with AUTOCOMMIT=1, then MySQL immediately writes each SQL statement to the binlog when the statement has been completed. No need to add "BEGIN" ... "COMMIT" around such statements. Otherwise, MySQL uses thd->transaction.trans_log to cache the SQL statements until the explicit commit, and at the commit writes the contents in .trans_log to the binlog. We write the "BEGIN" mark first in the buffer (.trans_log) where we store the SQL statements for a transaction. At the transaction commit we will add the "COMMIT mark and write the buffer to the binlog. The function my_b_tell above returns != 0 if there already is data in the buffer. */ int save_query_length = thd->query_length; thd->query_length = 5; /* length of string BEGIN */ Query_log_event qinfo(thd, "BEGIN", TRUE); error = ((&qinfo)->write(file)); thd->query_length = save_query_length; if (error) goto err; } if (thd->last_insert_id_used) { Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id); Loading Loading
sql/handler.cc +31 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ int ha_autocommit_or_rollback(THD *thd, int error) } else (void) ha_rollback_stmt(thd); thd->tx_isolation=thd->session_tx_isolation; } #endif Loading Loading @@ -309,6 +310,36 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if (trans == &thd->transaction.all && mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log)) { /* We write the command "COMMIT" as the last SQL command in the binlog segment cached for this transaction */ int save_query_length = thd->query_length; thd->query_length = 6; /* length of 'COMMIT'; note that we may come here because a DROP TABLE, for instance, makes an implicit commit, and then thd->query is not 'COMMIT'! */ Query_log_event qinfo(thd, "COMMIT", TRUE); /* When we come here, and the user wrapped the transaction into BEGIN and COMMIT, then qinfo got above the field cache_stmt erroneously set to 0. Let us set it to 1: */ qinfo.cache_stmt = 1; /* Write the 'COMMIT' entry to the cache */ if (mysql_bin_log.write(&qinfo)) { my_error(ER_ERROR_DURING_COMMIT, MYF(0), 5000); error=1; } thd->query_length = save_query_length; /* Now we write the binlog segment cached for this transaction to the real binlog */ mysql_bin_log.write(thd, &thd->transaction.trans_log); reinit_io_cache(&thd->transaction.trans_log, WRITE_CACHE, (my_off_t) 0, 0, 1); Loading
sql/log.cc +36 −4 Original line number Diff line number Diff line Loading @@ -442,8 +442,8 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) #ifdef HAVE_FTRUNCATE if (ftruncate(index_file,0)) { sql_print_error("Could not truncate the binlog index file \ during log purge for write"); sql_print_error( "Could not truncate the binlog index file during log purge for write"); error = LOG_INFO_FATAL; goto err; } Loading @@ -455,8 +455,8 @@ during log purge for write"); O_CREAT | O_BINARY | O_RDWR | O_APPEND, MYF(MY_WME)))) { sql_print_error("Could not re-open the binlog index file \ during log purge for write"); sql_print_error( "Could not re-open the binlog index file during log purge for write"); error = LOG_INFO_FATAL; goto err; } Loading Loading @@ -661,6 +661,38 @@ bool MYSQL_LOG::write(Query_log_event* event_info) error=1; if (file == &thd->transaction.trans_log && !my_b_tell(&thd->transaction.trans_log)) { /* Add the "BEGIN" and "COMMIT" in the binlog around transactions which may contain more than 1 SQL statement. If we run with AUTOCOMMIT=1, then MySQL immediately writes each SQL statement to the binlog when the statement has been completed. No need to add "BEGIN" ... "COMMIT" around such statements. Otherwise, MySQL uses thd->transaction.trans_log to cache the SQL statements until the explicit commit, and at the commit writes the contents in .trans_log to the binlog. We write the "BEGIN" mark first in the buffer (.trans_log) where we store the SQL statements for a transaction. At the transaction commit we will add the "COMMIT mark and write the buffer to the binlog. The function my_b_tell above returns != 0 if there already is data in the buffer. */ int save_query_length = thd->query_length; thd->query_length = 5; /* length of string BEGIN */ Query_log_event qinfo(thd, "BEGIN", TRUE); error = ((&qinfo)->write(file)); thd->query_length = save_query_length; if (error) goto err; } if (thd->last_insert_id_used) { Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id); Loading