mirror of
https://github.com/MariaDB/server.git
synced 2025-08-17 21:39:33 +00:00

There are two problems. First, replication fails when XA transactions are used where the slave has replicate_do_db set and the client has touched a different database when running DML such as inserts. This is because XA commands are not treated as keywords, and are thereby not exempt from the replication filter. The effect of this is that during an XA transaction, if its logged “use db” from the master is filtered out by the replication filter, then XA END will be ignored, yet its corresponding XA PREPARE will be executed in an invalid state, thereby breaking replication. Second, if the slave replicates an XA transaction which results in an empty transaction, the XA START through XA PREPARE first phase of the transaction won’t be binlogged, yet the XA COMMIT will be binlogged. This will break replication in chain configurations. The first problem is fixed by treating XA commands in Query_log_event as keywords, thus allowing them to bypass the replication filter. Note that Query_log_event::is_trans_keyword() is changed to accept a new parameter to define its mode, to either check for XA commands or regular transaction commands, but not both. In addition, mysqlbinlog is adapted to use this mode so its --database filter does not remove XA commands from its output. The second problem fixed by overwriting the XA state in the XID cache to be XA_ROLLBACK_ONLY, so at commit time, the server knows to rollback the transaction and skip its binlogging. If the xid cache is cleared before an XA transaction receives its completion command (e.g. on server shutdown), then before reporting ER_XAER_NOTA when the completion command is executed, the filter is first checked if the database is ignored, and if so, the error is ignored. Reviewed By: ============ Kristian Nielsen <knielsen@knielsen-hq.org> Andrei Elkin <andrei.elkin@mariadb.com>
58 lines
1.7 KiB
C++
58 lines
1.7 KiB
C++
#ifndef XA_INCLUDED
|
|
#define XA_INCLUDED
|
|
/*
|
|
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
|
Copyright (c) 2009, 2019, MariaDB Corporation.
|
|
|
|
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 Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
class XID_cache_element;
|
|
enum xa_states
|
|
{
|
|
XA_ACTIVE= 0,
|
|
XA_IDLE,
|
|
XA_PREPARED,
|
|
XA_ROLLBACK_ONLY,
|
|
XA_NO_STATE
|
|
};
|
|
|
|
struct XID_STATE {
|
|
XID_cache_element *xid_cache_element;
|
|
|
|
bool check_has_uncommitted_xa() const;
|
|
bool is_explicit_XA() const { return xid_cache_element != 0; }
|
|
void set_error(uint error);
|
|
void set_rollback_only();
|
|
void er_xaer_rmfail() const;
|
|
XID *get_xid() const;
|
|
enum xa_states get_state_code() const;
|
|
};
|
|
|
|
void xid_cache_init(void);
|
|
void xid_cache_free(void);
|
|
bool xid_cache_insert(XID *xid);
|
|
bool xid_cache_insert(THD *thd, XID_STATE *xid_state, XID *xid);
|
|
void xid_cache_delete(THD *thd, XID_STATE *xid_state);
|
|
|
|
bool trans_xa_start(THD *thd);
|
|
bool trans_xa_end(THD *thd);
|
|
bool trans_xa_prepare(THD *thd);
|
|
bool trans_xa_commit(THD *thd);
|
|
bool trans_xa_rollback(THD *thd);
|
|
bool trans_xa_detach(THD *thd);
|
|
bool mysql_xa_recover(THD *thd);
|
|
|
|
#endif /* XA_INCLUDED */
|