diff options
author | Alexander Nozdrin <alik@sun.com> | 2010-08-30 18:07:40 +0400 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2010-08-30 18:07:40 +0400 |
commit | f0fe6e4dac44c9555de1193990e9d2cbc77be62e (patch) | |
tree | 0a5202757c09044f2c476f93621c75c9df31e32d /sql/sql_class.cc | |
parent | b7ed981f3793b4464b99c98b7baa3c511b52b6a5 (diff) | |
parent | 9ab0759ea4534c1581dfb62f2f7e3a6e06d3c3c3 (diff) | |
download | mariadb-git-f0fe6e4dac44c9555de1193990e9d2cbc77be62e.tar.gz |
Auto-merge from mysql-5.5-merge.
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 131 |
1 files changed, 14 insertions, 117 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 626173fedce..f65e5c05826 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -307,6 +307,11 @@ void **thd_ha_data(const THD *thd, const struct handlerton *hton) return (void **) &thd->ha_data[hton->slot].ha_ptr; } +extern "C" +void thd_storage_lock_wait(THD *thd, long long value) +{ + thd->utime_after_lock+= value; +} /** Provide a handler data getter to simplify coding @@ -3841,124 +3846,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; + 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 (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); - } + 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 |