summaryrefslogtreecommitdiff
path: root/sql/transaction.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/transaction.cc')
-rw-r--r--sql/transaction.cc25
1 files changed, 20 insertions, 5 deletions
diff --git a/sql/transaction.cc b/sql/transaction.cc
index d3e3ba142b9..b331fea89fe 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -21,6 +21,7 @@
#include "sql_priv.h"
#include "transaction.h"
#include "rpl_handler.h"
+#include "debug_sync.h" // DEBUG_SYNC
/* Conditions under which the transaction state must not change. */
static bool trans_check(THD *thd)
@@ -391,15 +392,15 @@ bool trans_savepoint(THD *thd, LEX_STRING name)
thd->transaction.savepoints= newsv;
/*
- Remember the last acquired lock before the savepoint was set.
- This is used as a marker to only release locks acquired after
+ Remember locks acquired before the savepoint was set.
+ They are used as a marker to only release locks acquired after
the setting of this savepoint.
Note: this works just fine if we're under LOCK TABLES,
since mdl_savepoint() is guaranteed to be beyond
the last locked table. This allows to release some
locks acquired during LOCK TABLES.
*/
- newsv->mdl_savepoint = thd->mdl_context.mdl_savepoint();
+ newsv->mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_RETURN(FALSE);
}
@@ -645,17 +646,31 @@ bool trans_xa_commit(THD *thd)
}
else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
{
- if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, FALSE))
+ MDL_request mdl_request;
+
+ /*
+ Acquire metadata lock which will ensure that COMMIT is blocked
+ by active FLUSH TABLES WITH READ LOCK (and vice versa COMMIT in
+ progress blocks FTWRL).
+
+ We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
+ */
+ mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_TRANSACTION);
+
+ if (thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout))
{
ha_rollback_trans(thd, TRUE);
my_error(ER_XAER_RMERR, MYF(0));
}
else
{
+ DEBUG_SYNC(thd, "trans_xa_commit_after_acquire_commit_lock");
+
res= test(ha_commit_one_phase(thd, 1));
if (res)
my_error(ER_XAER_RMERR, MYF(0));
- thd->global_read_lock.start_waiting_global_read_lock(thd);
}
}
else