Commit d04e1d4b authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-15029 XA COMMIT and XA ROLLBACK operate on freed transaction object

innobase_commit_by_xid(), innobase_rollback_by_xid(): Decrement
the reference count before freeing the transaction object to the pool.
Failure to do so might corrupt the transaction bookkeeping
if trx_create_low() returns the same object to another thread
before we are done with it.

trx_sys_close(): Detach the recovered XA PREPARE transactions from
trx_sys->rw_trx_list before freeing them.
parent 9b4dfdaa
...@@ -17881,12 +17881,14 @@ innobase_commit_by_xid( ...@@ -17881,12 +17881,14 @@ innobase_commit_by_xid(
} }
if (trx_t* trx = trx_get_trx_by_xid(xid)) { if (trx_t* trx = trx_get_trx_by_xid(xid)) {
TrxInInnoDB trx_in_innodb(trx); ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE);
innobase_commit_low(trx);
ut_ad(trx->mysql_thd == NULL);
/* use cases are: disconnected xa, slave xa, recovery */ /* use cases are: disconnected xa, slave xa, recovery */
trx_deregister_from_2pc(trx); {
TrxInInnoDB trx_in_innodb(trx);
innobase_commit_low(trx);
ut_ad(trx->mysql_thd == NULL);
trx_deregister_from_2pc(trx);
}
ut_ad(!trx->will_lock); /* trx cache requirement */ ut_ad(!trx->will_lock); /* trx cache requirement */
trx_free_for_background(trx); trx_free_for_background(trx);
...@@ -17915,12 +17917,14 @@ innobase_rollback_by_xid( ...@@ -17915,12 +17917,14 @@ innobase_rollback_by_xid(
} }
if (trx_t* trx = trx_get_trx_by_xid(xid)) { if (trx_t* trx = trx_get_trx_by_xid(xid)) {
TrxInInnoDB trx_in_innodb(trx); int ret;
ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE);
int ret = innobase_rollback_trx(trx); {
TrxInInnoDB trx_in_innodb(trx);
trx_deregister_from_2pc(trx); ret = innobase_rollback_trx(trx);
ut_ad(!trx->will_lock); trx_deregister_from_2pc(trx);
ut_ad(!trx->will_lock);
}
trx_free_for_background(trx); trx_free_for_background(trx);
return(ret); return(ret);
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -939,13 +939,9 @@ trx_sys_close(void) ...@@ -939,13 +939,9 @@ trx_sys_close(void)
|| srv_read_only_mode || srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); while (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) {
trx != NULL;
trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) {
trx_free_prepared(trx);
UT_LIST_REMOVE(trx_sys->rw_trx_list, trx); UT_LIST_REMOVE(trx_sys->rw_trx_list, trx);
trx_free_prepared(trx);
} }
/* There can't be any active transactions. */ /* There can't be any active transactions. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment