diff options
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 128 |
1 files changed, 10 insertions, 118 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index eff7d8c1d90..bde56777d52 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3775,124 +3775,16 @@ int THD::decide_logging_format(TABLE_LIST *tables) int error= 0; int unsafe_flags; - /* - Classify a statement as unsafe when there is a mixed statement and an - on-going transaction at any point of the execution if: - - 1. The mixed statement is about to update a transactional table and - a non-transactional table. - - 2. The mixed statement is about to update a temporary transactional - table and a non-transactional table. - - 3. The mixed statement is about to update a transactional table and - read from a non-transactional table. - - 4. The mixed statement is about to update a temporary transactional - table and read from a non-transactional table. - - 5. The mixed statement is about to update a non-transactional table - and read from a transactional table when the isolation level is - lower than repeatable read. - - After updating a transactional table if: - - 6. The mixed statement is about to update a non-transactional table - and read from a temporary transactional table. - - 7. The mixed statement is about to update a non-transactional table - and read from a temporary transactional table. - - 8. The mixed statement is about to update a non-transactionala table - and read from a temporary non-transactional table. - - 9. The mixed statement is about to update a temporary non-transactional - table and update a non-transactional table. - - 10. The mixed statement is about to update a temporary non-transactional - table and read from a non-transactional table. - - 11. A statement is about to update a non-transactional table and the - option variables.binlog_direct_non_trans_update is OFF. - - The reason for this is that locks acquired may not protected a concurrent - transaction of interfering in the current execution and by consequence in - the result. In particular, if there is an on-going transaction and a - transactional table was already updated, a temporary table must be written - to the binary log in the boundaries of the on-going transaction and as - such we artificially classify them as transactional. - */ - if (in_multi_stmt_transaction_mode()) - { - my_bool mixed_unsafe= FALSE; - my_bool non_trans_unsafe= FALSE; - - /* Case 1. */ - if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 2. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 3. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 4. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 5. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE) && - tx_isolation < ISO_REPEATABLE_READ) - /* - By default, InnoDB operates in REPEATABLE READ and with the option - --innodb-locks-unsafe-for-binlog disabled. In this case, InnoDB uses - next-key locks for searches and index scans, which prevents phantom - rows. - - This is scenario is safe for Innodb. However, there are no means to - transparently get this information. Therefore, we need to improve this - and change the storage engines to report somehow when an execution is - safe under an isolation level & binary logging format. - */ - mixed_unsafe= TRUE; - - if (trans_has_updated_trans_table(this)) - { - /* Case 6. */ - if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 7. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_TEMP_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 8. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_TEMP_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 9. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 10. */ - else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) && - lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE)) - mixed_unsafe= TRUE; - /* Case 11. */ - else if (!variables.binlog_direct_non_trans_update && - lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE)) - non_trans_unsafe= TRUE; - } - - if (mixed_unsafe) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MIXED_STATEMENT); - else if (non_trans_unsafe) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_NONTRANS_AFTER_TRANS); - } + bool multi_stmt_trans= in_multi_stmt_transaction_mode(); + bool trans_table= trans_has_updated_trans_table(this); + bool binlog_direct= variables.binlog_direct_non_trans_update; + + if (lex->is_mixed_stmt_unsafe(multi_stmt_trans, binlog_direct, + trans_table, tx_isolation)) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MIXED_STATEMENT); + else if (multi_stmt_trans && trans_table && !binlog_direct && + lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE)) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_NONTRANS_AFTER_TRANS); /* If more than one engine is involved in the statement and at |