summaryrefslogtreecommitdiff
path: root/sql/transaction.cc
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2019-04-18 14:43:40 +0400
committerSergey Vojtovich <svoj@mariadb.org>2019-04-25 15:06:40 +0400
commit07140f171d8c81d241ef4fd7e8e53afa2d269b16 (patch)
tree18201b76c97e4511a9cb8967c11031bec52f6a60 /sql/transaction.cc
parentca7fbcea6c4fe13c295cf43b80d05351aba59e95 (diff)
downloadmariadb-git-07140f171d8c81d241ef4fd7e8e53afa2d269b16.tar.gz
Just move, no code changes otherwise.
Part of MDEV-7974 - backport fix for mysql bug#12161 (XA and binlog)
Diffstat (limited to 'sql/transaction.cc')
-rw-r--r--sql/transaction.cc332
1 files changed, 3 insertions, 329 deletions
diff --git a/sql/transaction.cc b/sql/transaction.cc
index 4d61d2a120d..15c45425528 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -28,21 +28,19 @@
#include "wsrep_trans_observer.h"
#endif /* WITH_WSREP */
-#ifndef EMBEDDED_LIBRARY
/**
Helper: Tell tracker (if any) that transaction ended.
*/
-static void trans_track_end_trx(THD *thd)
+void trans_track_end_trx(THD *thd)
{
+#ifndef EMBEDDED_LIBRARY
if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
{
((Transaction_state_tracker *)
thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER))->end_trx(thd);
}
-}
-#else
-#define trans_track_end_trx(A) do{}while(0)
#endif //EMBEDDED_LIBRARY
+}
/**
@@ -89,65 +87,6 @@ static bool trans_check(THD *thd)
/**
- Mark a XA transaction as rollback-only if the RM unilaterally
- rolled back the transaction branch.
-
- @note If a rollback was requested by the RM, this function sets
- the appropriate rollback error code and transits the state
- to XA_ROLLBACK_ONLY.
-
- @return TRUE if transaction was rolled back or if the transaction
- state is XA_ROLLBACK_ONLY. FALSE otherwise.
-*/
-static bool xa_trans_rolled_back(XID_STATE *xid_state)
-{
- if (xid_state->rm_error)
- {
- switch (xid_state->rm_error) {
- case ER_LOCK_WAIT_TIMEOUT:
- my_error(ER_XA_RBTIMEOUT, MYF(0));
- break;
- case ER_LOCK_DEADLOCK:
- my_error(ER_XA_RBDEADLOCK, MYF(0));
- break;
- default:
- my_error(ER_XA_RBROLLBACK, MYF(0));
- }
- xid_state->xa_state= XA_ROLLBACK_ONLY;
- }
-
- return (xid_state->xa_state == XA_ROLLBACK_ONLY);
-}
-
-
-/**
- Rollback the active XA transaction.
-
- @note Resets rm_error before calling ha_rollback(), so
- the thd->transaction.xid structure gets reset
- by ha_rollback() / THD::transaction::cleanup().
-
- @return TRUE if the rollback failed, FALSE otherwise.
-*/
-
-static bool xa_trans_force_rollback(THD *thd)
-{
- /*
- We must reset rm_error before calling ha_rollback(),
- so thd->transaction.xid structure gets reset
- by ha_rollback()/THD::transaction::cleanup().
- */
- thd->transaction.xid_state.rm_error= 0;
- if (ha_rollback_trans(thd, true))
- {
- my_error(ER_XAER_RMERR, MYF(0));
- return true;
- }
- return false;
-}
-
-
-/**
Begin a new transaction.
@note Beginning a transaction implicitly commits any current
@@ -777,268 +716,3 @@ bool trans_release_savepoint(THD *thd, LEX_CSTRING name)
DBUG_RETURN(MY_TEST(res));
}
-
-
-/**
- Starts an XA transaction with the given xid value.
-
- @param thd Current thread
-
- @retval FALSE Success
- @retval TRUE Failure
-*/
-
-bool trans_xa_start(THD *thd)
-{
- enum xa_states xa_state= thd->transaction.xid_state.xa_state;
- DBUG_ENTER("trans_xa_start");
-
- if (xa_state == XA_IDLE && thd->lex->xa_opt == XA_RESUME)
- {
- bool not_equal= !thd->transaction.xid_state.xid.eq(thd->lex->xid);
- if (not_equal)
- my_error(ER_XAER_NOTA, MYF(0));
- else
- thd->transaction.xid_state.xa_state= XA_ACTIVE;
- DBUG_RETURN(not_equal);
- }
-
- /* TODO: JOIN is not supported yet. */
- if (thd->lex->xa_opt != XA_NONE)
- my_error(ER_XAER_INVAL, MYF(0));
- else if (xa_state != XA_NOTR)
- my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
- else if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction())
- my_error(ER_XAER_OUTSIDE, MYF(0));
- else if (!trans_begin(thd))
- {
- DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
- thd->transaction.xid_state.xa_state= XA_ACTIVE;
- thd->transaction.xid_state.rm_error= 0;
- thd->transaction.xid_state.xid.set(thd->lex->xid);
- if (xid_cache_insert(thd, &thd->transaction.xid_state))
- {
- thd->transaction.xid_state.xa_state= XA_NOTR;
- thd->transaction.xid_state.xid.null();
- trans_rollback(thd);
- DBUG_RETURN(true);
- }
- DBUG_RETURN(FALSE);
- }
-
- DBUG_RETURN(TRUE);
-}
-
-
-/**
- Put a XA transaction in the IDLE state.
-
- @param thd Current thread
-
- @retval FALSE Success
- @retval TRUE Failure
-*/
-
-bool trans_xa_end(THD *thd)
-{
- DBUG_ENTER("trans_xa_end");
-
- /* TODO: SUSPEND and FOR MIGRATE are not supported yet. */
- if (thd->lex->xa_opt != XA_NONE)
- my_error(ER_XAER_INVAL, MYF(0));
- else if (thd->transaction.xid_state.xa_state != XA_ACTIVE)
- my_error(ER_XAER_RMFAIL, MYF(0),
- xa_state_names[thd->transaction.xid_state.xa_state]);
- else if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
- my_error(ER_XAER_NOTA, MYF(0));
- else if (!xa_trans_rolled_back(&thd->transaction.xid_state))
- thd->transaction.xid_state.xa_state= XA_IDLE;
-
- DBUG_RETURN(thd->is_error() ||
- thd->transaction.xid_state.xa_state != XA_IDLE);
-}
-
-
-/**
- Put a XA transaction in the PREPARED state.
-
- @param thd Current thread
-
- @retval FALSE Success
- @retval TRUE Failure
-*/
-
-bool trans_xa_prepare(THD *thd)
-{
- DBUG_ENTER("trans_xa_prepare");
-
- if (thd->transaction.xid_state.xa_state != XA_IDLE)
- my_error(ER_XAER_RMFAIL, MYF(0),
- xa_state_names[thd->transaction.xid_state.xa_state]);
- else if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
- my_error(ER_XAER_NOTA, MYF(0));
- else if (ha_prepare(thd))
- {
- xid_cache_delete(thd, &thd->transaction.xid_state);
- thd->transaction.xid_state.xa_state= XA_NOTR;
- my_error(ER_XA_RBROLLBACK, MYF(0));
- }
- else
- thd->transaction.xid_state.xa_state= XA_PREPARED;
-
- DBUG_RETURN(thd->is_error() ||
- thd->transaction.xid_state.xa_state != XA_PREPARED);
-}
-
-
-/**
- Commit and terminate the a XA transaction.
-
- @param thd Current thread
-
- @retval FALSE Success
- @retval TRUE Failure
-*/
-
-bool trans_xa_commit(THD *thd)
-{
- bool res= TRUE;
- enum xa_states xa_state= thd->transaction.xid_state.xa_state;
- DBUG_ENTER("trans_xa_commit");
-
- if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
- {
- if (thd->fix_xid_hash_pins())
- {
- my_error(ER_OUT_OF_RESOURCES, MYF(0));
- DBUG_RETURN(TRUE);
- }
-
- XID_STATE *xs= xid_cache_search(thd, thd->lex->xid);
- res= !xs;
- if (res)
- my_error(ER_XAER_NOTA, MYF(0));
- else
- {
- res= xa_trans_rolled_back(xs);
- ha_commit_or_rollback_by_xid(thd->lex->xid, !res);
- xid_cache_delete(thd, xs);
- }
- DBUG_RETURN(res);
- }
-
- if (xa_trans_rolled_back(&thd->transaction.xid_state))
- {
- xa_trans_force_rollback(thd);
- res= thd->is_error();
- }
- else if (xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
- {
- int r= ha_commit_trans(thd, TRUE);
- if ((res= MY_TEST(r)))
- my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
- }
- else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
- {
- 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::BACKUP, "", "", MDL_BACKUP_COMMIT,
- 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= MY_TEST(ha_commit_one_phase(thd, 1));
- if (res)
- my_error(ER_XAER_RMERR, MYF(0));
- }
- }
- else
- {
- my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
- DBUG_RETURN(TRUE);
- }
-
- thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
- thd->transaction.all.reset();
- thd->server_status&=
- ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
- DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
- xid_cache_delete(thd, &thd->transaction.xid_state);
- thd->transaction.xid_state.xa_state= XA_NOTR;
-
- trans_track_end_trx(thd);
-
- DBUG_RETURN(res);
-}
-
-
-/**
- Roll back and terminate a XA transaction.
-
- @param thd Current thread
-
- @retval FALSE Success
- @retval TRUE Failure
-*/
-
-bool trans_xa_rollback(THD *thd)
-{
- bool res= TRUE;
- enum xa_states xa_state= thd->transaction.xid_state.xa_state;
- DBUG_ENTER("trans_xa_rollback");
-
- if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
- {
- if (thd->fix_xid_hash_pins())
- {
- my_error(ER_OUT_OF_RESOURCES, MYF(0));
- DBUG_RETURN(TRUE);
- }
-
- XID_STATE *xs= xid_cache_search(thd, thd->lex->xid);
- if (!xs)
- my_error(ER_XAER_NOTA, MYF(0));
- else
- {
- xa_trans_rolled_back(xs);
- ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
- xid_cache_delete(thd, xs);
- }
- DBUG_RETURN(thd->get_stmt_da()->is_error());
- }
-
- if (xa_state != XA_IDLE && xa_state != XA_PREPARED && xa_state != XA_ROLLBACK_ONLY)
- {
- my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
- DBUG_RETURN(TRUE);
- }
-
- res= xa_trans_force_rollback(thd);
-
- thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
- thd->transaction.all.reset();
- thd->server_status&=
- ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
- DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
- xid_cache_delete(thd, &thd->transaction.xid_state);
- thd->transaction.xid_state.xa_state= XA_NOTR;
-
- trans_track_end_trx(thd);
-
- DBUG_RETURN(res);
-}