Bug #51564 | Error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS is too eager after BUG#46364 | ||
---|---|---|---|
Submitted: | 26 Feb 2010 20:10 | Modified: | 26 Apr 2010 13:48 |
Reporter: | Alfranio Tavares Correia Junior | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S3 (Non-critical) |
Version: | 5.5.99-m3 | OS: | Any |
Assigned to: | Alfranio Tavares Correia Junior | CPU Architecture: | Any |
Tags: | consistency, myisam, non-transactional changes |
[26 Feb 2010 20:10]
Alfranio Tavares Correia Junior
[26 Feb 2010 20:48]
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/101727 2974 Alfranio Correia 2010-02-26 BUG#51291, BUG#51564 --- BUG#51291 Unfortunate effect around variable binlog_direct_non_transactional_updates The new option binlog_direct_non_transactional_updates does not mimic the behavior in 5.1 when set to OFF. This happens due to the following reasons: . non-transactional changes executed before all transactional changes are stored in the non-trx-cache in order to avoid tracking the the trx-cache and figuring out when it might be flushed. However, this could lead to the following scenario: EXECUTION: BEGIN; MIXED-STATEMENT; COMMIT; BINLOG ENTRIES: STMT-CACHE: ----------- BEGIN; TableMap on N; Write to N; COMMIT; TRX-CACHE: ---------- BEGIN; TableMap on T; Write to T; Write to N; COMMIT; This happens because changes to non-transactional engines go to the stmt-cache when there is no changes to transactional engines. However as soon as the first change to the transactional engine gets into the trx-cache, additional changes to transactional engines go to the trx-cache. Either the non-transactional changes go to the stmt-cache or to the trx-cache but using both caches may generate inconsistencies as the TableMap on N is not in the trx-cache. So as an unfortunate consequence, the slave simply ignores changes whose TableMap do no exist. Recall that TableMaps have a life-cycle in the context of a transaction and as such do not go beyond transaction's boundaries. . in mixed and row modes, the "binlog rollback" was not considering the fact that there might be non-transactional changes in the trx-cache and was truncating the cache. . in mixed and row modes, the "binlog rollback" was not considering the fact that there might be non-transactional changes in a failed statement and was truncating the cache. . there is no need to generate warning messages for changes to non-transactional engines in mixed statements or that happen after changes to transactional engines within a transaction's context. --- BUG#51564 Error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS is too eager after BUG#46364 Error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS is too eager after BUG#46364 because warning messages are being printed out for statements that only update non-transactional engines with the SBR mode. To fix the problem, we only print warning messages when mixed statements are executed with the SBR mode and create a new error message BINLOG_STMT_UNSAFE_MIXED_STATEMENT for this case.
[11 Mar 2010 16:49]
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/103032 2975 Alfranio Correia 2010-03-11 BUG#51291, BUG#51564 --- BUG#51291 Unfortunate effect around variable binlog_direct_non_transactional_updates The new option binlog_direct_non_transactional_updates does not mimic the behavior in 5.1 when set to OFF. This happens due to the following reasons: (1) non-transactional changes executed before all transactional changes are stored in the non-trx-cache in order to avoid tracking the the trx-cache and figuring out when it might be flushed. However, this could lead to the following scenario: EXECUTION: BEGIN; MIXED-STATEMENT; COMMIT; BINLOG ENTRIES: STMT-CACHE: ----------- BEGIN; TableMap on N; Write to N; COMMIT; TRX-CACHE: ---------- BEGIN; TableMap on T; Write to T; Write to N; COMMIT; This happens because changes to non-transactional engines go to the stmt-cache when there is no changes to transactional engines. However as soon as the first change to the transactional engine gets into the trx-cache, additional changes to transactional engines go to the trx-cache. Either the non-transactional changes should go to the stmt-cache or to the trx-cache but using both caches may generate inconsistencies as the TableMap on N is not in the trx-cache. So as an unfortunate consequence, the slave simply ignores changes whose TableMap do no exist. Recall that TableMaps have a life-cycle in the context of a transaction and as such do not go beyond transaction's boundaries. (2) in mixed and row modes, the "binlog rollback" was not considering the fact that there might be non-transactional changes in the trx-cache and was truncating the cache. (3) in mixed and row modes, the "binlog rollback" was not considering the fact that there might be non-transactional changes in a failed statement and was truncating the cache. To fix the problems described above and to facilitate the use of the option, we have decided that it will only affect the statement mode as in 5.1. The mixed and row modes shall be behave after the WL#2687. The statment mode shall behave as in 5.1 and, in this case, we use the stmt-cache to write n-statments ahead of the transaction. --- BUG#51564 Error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS is too eager after BUG#46364 Error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS is too eager after BUG#46364 because warning messages are being printed out for statements that only update non-transactional engines with the SBR mode. To fix the problem, we only print warning messages when mixed statements are executed with the SBR mode and create a new error message ER_BINLOG_UNSAFE_MIXED_STATEMENT for this case. @ mysql-test/extra/rpl_tests/rpl_mixing_engines.test Updated the test case to avoid checking inconsistencies between the master and slave when session.binlog_direct_non_transactional_updates is ON and the format is statement. In this scenario, they will diverge because a counter (within a triger) is incremented and associated to the issued statement. However, an n-statement is logged ahead of the transaction and thus is not executed by the same order in the slave and thus gets a different value from the counter. @ mysql-test/suite/binlog/r/binlog_multi_engine.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ mysql-test/suite/ndb/r/ndb_binlog_format.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ mysql-test/suite/rpl/r/rpl_concurrency_error.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result Removed the effects of the error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. In this case, there is no need to switch from statement to rows as the plain statement is logged ahead of the transaction. Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT too. @ mysql-test/suite/rpl/r/rpl_stm_binlog_max_cache_size.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ mysql-test/suite/rpl/r/rpl_stm_stop_middle_group.result Updated the test case with the new error ER_BINLOG_UNSAFE_MIXED_STATEMENT and removed the eager error ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS. @ sql/log.cc Introduced a flag at_least_one_stmt_committed that identifies if any statement was executed and its effects were written to the trx-cache. So when this flag is false, and we are in statement mode and the binlog_direct_non_trans_update, we can write to the stmt-cache if necessary (i.e an n-statement). @ sql/share/errmsg-utf8.txt Added the new unsafe error ER_BINLOG_UNSAFE_MIXED_STATEMENT. @ sql/sql_class.cc Avoided printing ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS when binlog_direct_non_transactional_updates is ON. Started printing ER_BINLOG_UNSAFE_MIXED_STATEMENT, when there is a mixed-statement. @ sql/sql_lex.cc Added the new unsafe error ER_BINLOG_UNSAFE_MIXED_STATEMENT. @ sql/sql_lex.h Added the new unsafe error ER_BINLOG_UNSAFE_MIXED_STATEMENT.
[26 Apr 2010 13:48]
Jon Stephens
Since there's no change to document, no changelog entry is needed. Updated this Caution: You should avoid transactions that update both transactional and nontransactional tables in a replication environment. that appears at http://dev.mysql.com/doc/refman/5.1/en/replication-features-transactions.html (including 5.0, 5.4, 5.5, and 6.0 versions), so that it now reads: You should avoid transactions that update both transactional and nontransactional tables in a replication environment. You should also avoid using any statement that reads from both transactional and nontransactional tables and writes to any of them. Closed.