diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index b334e003851..ebe5ea5d4fa 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -952,16 +952,21 @@ int ha_prepare(THD *thd) A helper function to evaluate if two-phase commit is mandatory. As a side effect, propagates the read-only/read-write flags of the statement transaction to its enclosing normal transaction. - - @retval TRUE we must run a two-phase commit. Returned - if we have at least two engines with read-write changes. - @retval FALSE Don't need two-phase commit. Even if we have two - transactional engines, we can run two independent - commits if changes in one of the engines are read-only. + + If we have at least two engines with read-write changes we must + run a two-phase commit. Otherwise we can run several independent + commits as the only transactional engine has read-write changes + and others are read-only. + + @retval 0 All engines are read-only. + @retval 1 We have the only engine with read-write changes. + @retval >1 More than one engine have read-write changes. + Note: return value might NOT be the exact number of + engines with read-write changes. */ static -bool +uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, bool all) { @@ -998,7 +1003,7 @@ ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, break; } } - return rw_ha_count > 1; + return rw_ha_count; } @@ -1061,19 +1066,30 @@ int ha_commit_trans(THD *thd, bool all) #ifdef USING_TRANSACTIONS if (ha_info) { - bool must_2pc; + uint rw_ha_count; + bool rw_trans; + + DBUG_EXECUTE_IF("crash_commit_before", abort();); + + /* Close all cursors that can not survive COMMIT */ + if (is_real_trans) /* not a statement commit */ + thd->stmt_map.close_transient_cursors(); - if (is_real_trans && wait_if_global_read_lock(thd, 0, 0)) + rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all); + /* rw_trans is TRUE when we in a transaction changing data */ + rw_trans= is_real_trans && (rw_ha_count > 0); + + if (rw_trans && + wait_if_global_read_lock(thd, 0, 0)) { ha_rollback_trans(thd, all); DBUG_RETURN(1); } - if ( is_real_trans - && opt_readonly - && ! (thd->security_ctx->master_access & SUPER_ACL) - && ! thd->slave_thread - ) + if (rw_trans && + opt_readonly && + !(thd->security_ctx->master_access & SUPER_ACL) && + !thd->slave_thread) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); ha_rollback_trans(thd, all); @@ -1081,15 +1097,7 @@ int ha_commit_trans(THD *thd, bool all) goto end; } - DBUG_EXECUTE_IF("crash_commit_before", abort();); - - /* Close all cursors that can not survive COMMIT */ - if (is_real_trans) /* not a statement commit */ - thd->stmt_map.close_transient_cursors(); - - must_2pc= ha_check_and_coalesce_trx_read_only(thd, ha_info, all); - - if (!trans->no_2pc && must_2pc) + if (!trans->no_2pc && (rw_ha_count > 1)) { for (; ha_info && !error; ha_info= ha_info->next()) { @@ -1129,7 +1137,7 @@ int ha_commit_trans(THD *thd, bool all) tc_log->unlog(cookie, xid); DBUG_EXECUTE_IF("crash_commit_after", abort();); end: - if (is_real_trans) + if (rw_trans) start_waiting_global_read_lock(thd); } #endif /* USING_TRANSACTIONS */ @@ -2730,6 +2738,8 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) } } } + if (table->s->frm_version != FRM_VER_TRUE_VARCHAR) + return HA_ADMIN_NEEDS_ALTER; return check_for_upgrade(check_opt); } |