Bug #56184 | Rolled back transaction without non-trasactional table updated was binlogged | ||
---|---|---|---|
Submitted: | 23 Aug 2010 5:27 | Modified: | 13 May 2011 10:26 |
Reporter: | Libing Song | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S3 (Non-critical) |
Version: | 5.1, 5.5 | OS: | Any |
Assigned to: | Libing Song | CPU Architecture: | Any |
[23 Aug 2010 5:27]
Libing Song
[23 Aug 2010 17:04]
Sveta Smirnova
Thank you for the report. Verified as described.
[29 Nov 2010 5:40]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/125292 3350 Li-Bing.Song@sun.com 2010-11-29 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table Bug#56184 The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs. A transactional cache and a statement cache. When executing a transaction, statements modified only transactional tables are always put in transactional cache. statements modified non-transactional tables can be put in both caches. It depends on different situations. In this patch, a flag is added to mark if there is any statement modified non-transactional table is in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no any statement in it modified non-transactional table, else it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch. @ sql/binlog.cc Refactor reset_cache, it is divided into reset_trx_cache() and reset_stmt_cache(). Add code to fix this bug. @ sql/rpl_slave.cc OPTION_KEEP_LOG is replaced by stmt.modified_non_trans_table. Remove OPTION_KEEP_LOG from all code. @ sql/sql_parse.cc OPTION_KEEP_LOG is replaced by stmt.modified_non_trans_table. Remove OPTION_KEEP_LOG from all code. @ sql/sql_table.cc Set stmt.modified_non_trans_table after a temporary table has been dropped. @ sql/sys_vars.cc OPTION_KEEP_LOG is replaced by stmt.modified_non_trans_table. Remove OPTION_KEEP_LOG from all code. @ sql/transaction.cc OPTION_KEEP_LOG is replaced by stmt.modified_non_trans_table. Remove OPTION_KEEP_LOG from all code.
[4 Dec 2010 11:21]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/126039 3350 Li-Bing.Song@sun.com 2010-12-04 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table Bug#56184 The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs, a transactional cache and a statement cache. When executing a transaction, statements that modified only transactional tables are always put in transactional cache. Statements that modified non-transactional tables can be put in either transactional or non-transactional cache depending on different situations. In this patch, a flag is added to mark if there is any statement that modified non-transactional table in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no statement in it that modified a non-transactional table. Otherwise, it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch. @ sql/binlog.cc Refactor reset_cache, it is divided into reset_trx_cache() and reset_stmt_cache(). Add code to fix this bug. @ sql/binlog.h Removed trans_has_updated_non_trans_table() and stmt_has_updated_non_trans_table(). Added stmt_cannot_safe_rollback(); See also handler.h. @ sql/ha_ndbcluster.cc Refactoring modified_non_trans_table. @ sql/ha_ndbcluster_binlog.cc Refactoring modified_non_trans_table. @ sql/handler.cc Refactoring modified_non_trans_table. Call push_unsafe_rollback_warnings() to print detail unsafe rollback warnings. @ sql/handler.h Use unsafe_rollback_flags to replace modified_non_trans_table. At present, not only change of non-transactional table but also creation and drop of temporary table cannot be rolled back. So unsafe_rollback_flags is a suitable name to express the meaning and can store more detail information, as it was defined as a set of flags. @ sql/log_event.cc Refactoring modified_non_trans_table. @ sql/rpl_slave.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/share/errmsg-utf8.txt Added two warnings. @ sql/sp_head.cc Refactoring modified_non_trans_table. @ sql/sql_class.cc Refactoring modified_non_trans_table. @ sql/sql_class.h Refactoring modified_non_trans_table. Added THD::st_transactions::push_unsafe_rollback_warnings to print detail unsafe rollback information. @ sql/sql_delete.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sql_insert.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sql_lex.h Removed stmt_accessed_non_trans_temp_table(); It is useless after this patch. @ sql/sql_load.cc Refactoring modified_non_trans_table. @ sql/sql_parse.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/sql_priv.h Removed OPTION_KEEP_LOG. @ sql/sql_table.cc Call stmt.created_temp_table() after a temporary table has been created. Call stmt.dropped_temp_table() after a temporary table has been dropped. @ sql/sql_truncate.cc Refactoring modified_non_trans_table. @ sql/sql_update.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sys_vars.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code. @ sql/transaction.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code.
[9 Dec 2010 14:43]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/126432 3426 Li-Bing.Song@sun.com 2010-12-09 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table Bug#56184 The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs, a transactional cache and a statement cache. When executing a transaction, statements that modified only transactional tables are always put in transactional cache. Statements that modified non-transactional tables can be put in either transactional or non-transactional cache depending on different situations. In this patch, a flag is added to mark if there is any statement that modified non-transactional table in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no statement in it that modified a non-transactional table. Otherwise, it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch. @ sql/binlog.cc Refactor reset_cache, it is divided into reset_trx_cache() and reset_stmt_cache(). Add code to fix this bug. @ sql/binlog.h Removed trans_has_updated_non_trans_table() and stmt_has_updated_non_trans_table(). Added stmt_cannot_safe_rollback(); See also handler.h. @ sql/ha_ndbcluster.cc Refactoring modified_non_trans_table. @ sql/ha_ndbcluster_binlog.cc Refactoring modified_non_trans_table. @ sql/handler.cc Refactoring modified_non_trans_table. Call push_unsafe_rollback_warnings() to print detail unsafe rollback warnings. @ sql/handler.h Use unsafe_rollback_flags to replace modified_non_trans_table. At present, not only change of non-transactional table but also creation and drop of temporary table cannot be rolled back. So unsafe_rollback_flags is a suitable name to express the meaning and can store more detail information, as it was defined as a set of flags. @ sql/log_event.cc Refactoring modified_non_trans_table. @ sql/rpl_slave.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/share/errmsg-utf8.txt Added two warnings. @ sql/sp_head.cc Refactoring modified_non_trans_table. @ sql/sql_class.cc Refactoring modified_non_trans_table. @ sql/sql_class.h Refactoring modified_non_trans_table. Added THD::st_transactions::push_unsafe_rollback_warnings to print detail unsafe rollback information. @ sql/sql_delete.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sql_insert.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sql_lex.h Removed stmt_accessed_non_trans_temp_table(); It is useless after this patch. @ sql/sql_load.cc Refactoring modified_non_trans_table. @ sql/sql_parse.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/sql_priv.h Removed OPTION_KEEP_LOG. @ sql/sql_table.cc Call stmt.created_temp_table() after a temporary table has been created. Call stmt.dropped_temp_table() after a temporary table has been dropped. @ sql/sql_truncate.cc Refactoring modified_non_trans_table. @ sql/sql_update.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sys_vars.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code. @ sql/transaction.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code.
[13 Dec 2010 3:37]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/126591 3427 Li-Bing.Song@sun.com 2010-12-13 Post patch for BUG#56184
[13 Dec 2010 3:51]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/126593 3426 Li-Bing.Song@sun.com 2010-12-13 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table Bug#56184 The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs, a transactional cache and a statement cache. When executing a transaction, statements that modified only transactional tables are always put in transactional cache. Statements that modified non-transactional tables can be put in either transactional or non-transactional cache depending on different situations. In this patch, a flag is added to mark if there is any statement that modified non-transactional table in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no statement in it that modified a non-transactional table. Otherwise, it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch. @ sql/binlog.cc Refactor reset_cache, it is divided into reset_trx_cache() and reset_stmt_cache(). Add code to fix this bug. @ sql/binlog.h Removed trans_has_updated_non_trans_table() and stmt_has_updated_non_trans_table(). Added stmt_cannot_safe_rollback(); See also handler.h. @ sql/ha_ndbcluster.cc Refactoring modified_non_trans_table. @ sql/ha_ndbcluster_binlog.cc Refactoring modified_non_trans_table. @ sql/handler.cc Refactoring modified_non_trans_table. Call push_unsafe_rollback_warnings() to print detail unsafe rollback warnings. @ sql/handler.h Use unsafe_rollback_flags to replace modified_non_trans_table. At present, not only change of non-transactional table but also creation and drop of temporary table cannot be rolled back. So unsafe_rollback_flags is a suitable name to express the meaning and can store more detail information, as it was defined as a set of flags. @ sql/log_event.cc Refactoring modified_non_trans_table. @ sql/rpl_slave.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/share/errmsg-utf8.txt Added two warnings. @ sql/sp_head.cc Refactoring modified_non_trans_table. @ sql/sql_class.cc Refactoring modified_non_trans_table. @ sql/sql_class.h Refactoring modified_non_trans_table. Added THD::st_transactions::push_unsafe_rollback_warnings to print detail unsafe rollback information. @ sql/sql_delete.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sql_insert.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sql_lex.h Removed stmt_accessed_non_trans_temp_table(); It is useless after this patch. @ sql/sql_load.cc Refactoring modified_non_trans_table. @ sql/sql_parse.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/sql_priv.h Removed OPTION_KEEP_LOG. @ sql/sql_table.cc Call stmt.created_temp_table() after a temporary table has been created. Call stmt.dropped_temp_table() after a temporary table has been dropped. @ sql/sql_truncate.cc Refactoring modified_non_trans_table. @ sql/sql_update.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in the end of mysql_execute_command(). @ sql/sys_vars.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code. @ sql/transaction.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code.
[16 Dec 2010 2:59]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/127021 3427 Li-Bing.Song@sun.com 2010-12-16 Post patch for BUG#56184 @ sql/binlog.cc Added new class binlog_trx_cache_data, moved m_trx_cache_cannot_rollback to binlog_trx_cache_data.
[29 Dec 2010 6:24]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/127647 3428 Li-Bing.Song@sun.com 2010-12-29 BUG#56184 Rolled back transaction without non-trasactional table updated was binlogged Post patch. Removed all.modified_non_trans_table() from sql_update.cc and sql_insert.cc Corrected some comments. Refactoring binlog_cache_data and binlog_trx_cache_data. Moved functions supported only by transactional cache from binlog_cache_data to binlog_trx_cache_data. Modified test result file effected by the patch for this bug. @ sql/sql_table.cc Call stmt.created_temp_table() only when the table has been created successfully.
[29 Dec 2010 8:33]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/127650 3426 Li-Bing.Song@sun.com 2010-12-29 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table Bug#56184 The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs, a transactional cache and a statement cache. When executing a transaction, statements that modified only transactional tables are always put in transactional cache. Statements that modified non-transactional tables can be put in either transactional or non-transactional cache depending on different situations. In this patch, a flag is added to mark if there is any statement that modified non-transactional table in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no statement in it that modified a non-transactional table. Otherwise, it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. ****** Post patch for BUG#56184 ****** BUG#56184 Rolled back transaction without non-trasactional table updated was binlogged Post patch. Removed all.modified_non_trans_table() from sql_update.cc and sql_insert.cc Corrected some comments. Refactoring binlog_cache_data and binlog_trx_cache_data. Moved functions supported only by transactional cache from binlog_cache_data to binlog_trx_cache_data. Modified test result file effected by the patch for this bug. @ mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.inc Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_innodb.test Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_mixing_engines.inc Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_temp_error.test An auxaliary file for causing temporary error on slave SQL thread @ mysql-test/r/read_only_innodb.result Updated test result affected by this patch. @ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result Updated test result affected by this patch. @ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_row_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_innodb.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/t/rpl_DML_error.test Added test to verify this patch. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch. @ sql/binlog.cc Refactor reset_cache, it is divided into reset_trx_cache() and reset_stmt_cache(). Added new class binlog_trx_cache_data, moved m_trx_cache_cannot_rollback to binlog_trx_cache_data. Add code to fix this bug. @ sql/binlog.h Removed trans_has_updated_non_trans_table() and stmt_has_updated_non_trans_table(). Added stmt_cannot_safe_rollback(); See also handler.h. @ sql/ha_ndbcluster.cc Refactoring modified_non_trans_table. @ sql/ha_ndbcluster_binlog.cc Refactoring modified_non_trans_table. @ sql/handler.cc Refactoring modified_non_trans_table. Call push_unsafe_rollback_warnings() to print detail unsafe rollback warnings. @ sql/handler.h Use unsafe_rollback_flags to replace modified_non_trans_table. At present, not only change of non-transactional table but also creation and drop of temporary table cannot be rolled back. So unsafe_rollback_flags is a suitable name to express the meaning and can store more detail information, as it was defined as a set of flags. @ sql/log_event.cc Refactoring modified_non_trans_table. @ sql/rpl_slave.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/share/errmsg-utf8.txt Added two warnings. @ sql/sp_head.cc Refactoring modified_non_trans_table. @ sql/sql_class.cc Refactoring modified_non_trans_table. @ sql/sql_class.h Refactoring modified_non_trans_table. Added THD::st_transactions::push_unsafe_rollback_warnings to print detail unsafe rollback information. @ sql/sql_delete.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_insert.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_lex.h Removed stmt_accessed_non_trans_temp_table(); It is useless after this patch. @ sql/sql_load.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_parse.cc OPTION_KEEP_LOG is replaced by stmt.cannot_safe_rollback(). Remove OPTION_KEEP_LOG from all code. @ sql/sql_priv.h Removed OPTION_KEEP_LOG. @ sql/sql_table.cc Call stmt.created_temp_table() after a temporary table has been created. Call stmt.dropped_temp_table() after a temporary table has been dropped. @ sql/sql_truncate.cc Refactoring modified_non_trans_table. @ sql/sql_update.cc Refactoring modified_non_trans_table. Removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sys_vars.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code. @ sql/transaction.cc OPTION_KEEP_LOG is replaced by stmt.unsafe_rollback_flags. Remove OPTION_KEEP_LOG from all code. Added code in trans_commit_stmt and trans_rollback_stmt to merge statement's unsafe_rollback_flags into transactional unsafe_rollback_flags.
[30 Dec 2010 11:54]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/127712 3475 Li-Bing.Song@sun.com 2010-12-30 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs, a transactional cache and a statement cache. When executing a transaction, statements that modified only transactional tables are always put in transactional cache. Statements that modified non-transactional tables can be put in either transactional or non-transactional cache depending on different situations. In this patch, a flag is added to mark if there is any statement that modified non-transactional table in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no statement in it that modified a non-transactional table. Otherwise, it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. It also did some refactoring on code related to THD_TRANS::modified_non_trans_table and binlog_cache_data. @ mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.inc Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_innodb.test Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_mixing_engines.inc Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_temp_error.test An auxaliary file for causing temporary error on slave SQL thread @ mysql-test/r/read_only_innodb.result Updated test result affected by this patch. @ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result Updated test result affected by this patch. @ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_DML_error.result Added test to verify the patch for BUG#56184. @ mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result Added test to verify the patch for BUG#55798. @ mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_row_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_innodb.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/t/rpl_DML_error.test Added test to verify the patch for BUG#56184. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch for bug#55798. @ sql/binlog.cc Refactoring on binlog_cache_data. Added new class binlog_trx_cache_data, moved some binlog_cache_data's members which are necessary only for transactional cache to binlog_trx_cache_data. Removed changes_to_non_trans_temp_table_flag and related functions, it is useless after this patch. Fixed bug#56184. @ sql/binlog.h Removed trans_has_updated_non_trans_table() and stmt_has_updated_non_trans_table(). Added stmt_cannot_safe_rollback(); @ sql/ha_ndbcluster.cc Refactoring on modified_non_trans_table. @ sql/ha_ndbcluster_binlog.cc Refactoring on modified_non_trans_table. @ sql/handler.cc Refactoring on modified_non_trans_table. Call push_unsafe_rollback_warnings() to print detail unsafe rollback warnings. @ sql/handler.h Use unsafe_rollback_flags to replace modified_non_trans_table. At present, not only change of non-transactional table but also creation and drop of temporary table cannot be rolled back. So unsafe_rollback_flags is a reasonable name to express the meaning and can store more detail information, as it was defined as a set of flags. @ sql/log_event.cc Refactoring on modified_non_trans_table. @ sql/rpl_slave.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. @ sql/share/errmsg-utf8.txt Added two warnings in the patch for bug#56184. @ sql/sp_head.cc Refactoring on modified_non_trans_table. @ sql/sql_class.cc Refactoring on modified_non_trans_table. @ sql/sql_class.h Refactoring on modified_non_trans_table. Added THD::st_transactions::push_unsafe_rollback_warnings to print detail unsafe rollback information. @ sql/sql_delete.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_insert.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_lex.h Removed stmt_accessed_non_trans_temp_table(); It is useless after this patch. @ sql/sql_load.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_parse.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. @ sql/sql_priv.h OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. @ sql/sql_table.cc Call stmt.created_temp_table() after a temporary table has been created. Call stmt.dropped_temp_table() after a temporary table has been dropped. @ sql/sql_truncate.cc Refactoring on modified_non_trans_table. @ sql/sql_update.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sys_vars.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. Refactoring on modified_non_trans_table. @ sql/transaction.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. Added code in trans_commit_stmt and trans_rollback_stmt to merge statement's unsafe_rollback_flags into transactional unsafe_rollback_flags.
[30 Dec 2010 12:07]
Libing Song
The patch is too large to send by mail.
Attachment: bug56184.patch.tgz (application/x-compressed-tar, text), 32.99 KiB.
[5 Jan 2011 5:33]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/127930 3457 anders.song@greatopensource.com 2011-01-05 Bug#56184 Rolled back transaction without non-trasactional table updated was binlogged Bug#55798 Slave SQL retry on transaction inserts extra data into non-transaction table The transaction modified non-transactional table will be binlogged with ROLLBACK if it rolls back on master. It includes the case that all statements which modified non-transactional table are binlogged outside(before) the transaction. Example: BEGIN INSERT INTO trans-table; INSERT INOT non-trans-table; ROLLBACK it will be binlogged as: BEGIN INSERT INTO non-trans-table; COMMIT BEGIN INSERT INTO trans-table; ROLLBACK; All statements in the second binlogged transaction modify only transactional tables and are rolled back safely on master. So the second transaction should not be binlogged. After 5.5, there are two caches for binary logs, a transactional cache and a statement cache. When executing a transaction, statements that modified only transactional tables are always put in transactional cache. Statements that modified non-transactional tables can be put in either transactional or non-transactional cache depending on different situations. In this patch, a flag is added to mark if there is any statement that modified non-transactional table in transactional cache. When rolling back a transaction on master, transactional cache should not be flushed to binary log, if there is no statement in it that modified a non-transactional table. Otherwise, it should be flushed into binary log followed by 'ROLLBACK' statement. BUG#55798 When a temporary error(eg. Lock timeout) happens, Slave SQL thread will rollback the transaction and retry it again. But it is possible that the transaction cannot be rolled back safely. For example a non-transactional table has been modified by the transaction. It will make master and slave diversely. After this patch, SQL thread will not retry to execute a transaction which can not be rolled back safely if temporary error is encountered. It also did some refactoring on code related to THD_TRANS::modified_non_trans_table and binlog_cache_data. @ mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.inc Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_innodb.test Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_mixing_engines.inc Updated test affected by this patch. Masked the new error's error number for easier merging. @ mysql-test/extra/rpl_tests/rpl_temp_error.test An auxaliary file for causing temporary error on slave SQL thread @ mysql-test/r/read_only_innodb.result Updated test result affected by this patch. @ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result Updated test result affected by this patch. @ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_DML_error.result Added test to verify the patch for BUG#56184. @ mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result Added test to verify the patch for BUG#55798. @ mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_row_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_innodb.result Updated test result affected by this patch. @ mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result Updated test result affected by this patch. @ mysql-test/suite/rpl/t/rpl_DML_error.test Added test to verify the patch for BUG#56184. @ mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test Add test to verify this patch for bug#55798. @ sql/binlog.cc Refactoring on binlog_cache_data. Added new class binlog_trx_cache_data, moved some binlog_cache_data's members which are necessary only for transactional cache to binlog_trx_cache_data. Removed changes_to_non_trans_temp_table_flag and related functions, it is useless after this patch. Fixed bug#56184. @ sql/binlog.h Removed trans_has_updated_non_trans_table() and stmt_has_updated_non_trans_table(). Added stmt_cannot_safe_rollback(); @ sql/ha_ndbcluster.cc Refactoring on modified_non_trans_table. @ sql/ha_ndbcluster_binlog.cc Refactoring on modified_non_trans_table. @ sql/handler.cc Refactoring on modified_non_trans_table. Call push_unsafe_rollback_warnings() to print detail unsafe rollback warnings. @ sql/handler.h Use unsafe_rollback_flags to replace modified_non_trans_table. At present, not only change of non-transactional table but also creation and drop of temporary table cannot be rolled back. So unsafe_rollback_flags is a reasonable name to express the meaning and can store more detail information, as it was defined as a set of flags. @ sql/log_event.cc Refactoring on modified_non_trans_table. @ sql/rpl_slave.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. @ sql/share/errmsg-utf8.txt Added two warnings in the patch for bug#56184. @ sql/sp_head.cc Refactoring on modified_non_trans_table. @ sql/sql_class.cc Refactoring on modified_non_trans_table. @ sql/sql_class.h Refactoring on modified_non_trans_table. Added THD::st_transactions::push_unsafe_rollback_warnings to print detail unsafe rollback information. @ sql/sql_delete.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_insert.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_lex.h Removed stmt_accessed_non_trans_temp_table(); It is useless after this patch. @ sql/sql_load.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sql_parse.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. @ sql/sql_priv.h OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. @ sql/sql_table.cc Call stmt.created_temp_table() after a temporary table has been created. Call stmt.dropped_temp_table() after a temporary table has been dropped. @ sql/sql_truncate.cc Refactoring on modified_non_trans_table. @ sql/sql_update.cc Refactoring on modified_non_trans_table. And removed the code to set thd->transaction.all.modified_non_trans_table, it will be set in trans_commit_stmt and trans_rollback_stmt. @ sql/sys_vars.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. Refactoring on modified_non_trans_table. @ sql/transaction.cc OPTION_KEEP_LOG is useless since this patch, so removed OPTION_KEEP_LOG from all code. Added code in trans_commit_stmt and trans_rollback_stmt to merge statement's unsafe_rollback_flags into transactional unsafe_rollback_flags.
[13 May 2011 10:26]
Jon Stephens
Documented fix in the 5.6.3 changelog, as follows: A transaction was written to the binary log even when it did not update any nontransactional tables. Closed.