summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc60
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);
}