Details
-
Task
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
Description
Dispite prepare phase have been rich you will get nothing when doing a xa recover if the client get disconnected befor commit
In the following php script an error is generated to force the COMMIT to failed cf:XA COMMITEE and close the connection.
|
<?php
|
|
$dt = date_create();
|
$xid = date_timestamp_get($dt);
|
echo "xid : ".$xid;
|
|
$logger1 = new mysqli('localhost', 'root', 'xxxxx', 'test');
|
if (mysqli_connect_error()) {
|
die('Erreur de connexion (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
|
}
|
$potest = new mysqli('192.168.45.166', 'test', 'xxxxxxx', 'test');
|
if (mysqli_connect_error()) {
|
$logger1->close();
|
die('Erreur de connexion (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
|
}
|
|
echo 'SuccËs logger1 ' . $logger1->host_info . "\n";
|
echo 'SuccËs potest ' . $potest->host_info . "\n";
|
|
|
##################################
|
$queryXA = 'XA START "'.$xid.'"';
|
|
$queryRes = $logger1->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide logger1: ' . $logger1->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
$queryRes = $potest->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide potest: ' . $potest->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
##################################
|
|
|
##################################
|
$queryXA = 'INSERT INTO mthoxa(xamtho_tc) values ("'.$xid.'")';
|
$queryRes = $logger1->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide logger1: ' . $logger1->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
|
$queryRes = $potest->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide logger1: ' . $logger1->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
##################################
|
|
|
##################################
|
$queryXA = 'XA END "'.$xid.'"';
|
|
$queryRes = $logger1->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide logger1: ' . $logger1->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
$queryRes = $potest->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide potest: ' . $potest->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
##################################
|
|
|
##################################
|
$queryXA = 'XA PREPARE "'.$xid.'"';
|
$queryRes = $logger1->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide logger1: ' . $logger1->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
|
$queryRes = $potest->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide potest: ' . $potest->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
|
##################################
|
|
|
##################################
|
$queryXA = 'XA COMMIT "'.$xid.'"';
|
$queryRes = $logger1->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide logger1: ' . $logger1->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
|
$queryXA = 'XA COMMITEE "'.$xid.'"';
|
$queryRes = $potest->query($queryXA);
|
if (!$queryRes) {
|
$message = 'RequÍte invalide potest: ' . $potest->error . "\n";
|
$message .= 'RequÍte complËte : ' . $queryXA;
|
|
$queryXA = 'XA RECOVER';
|
$queryRes = $potest->query($queryXA);
|
while ($r=$queryRes->fetch_assoc())
|
print_r($r);
|
|
|
$logger1->close();
|
$potest->close();
|
die($message);
|
}
|
##################################
|
|
$logger1->close();
|
$potest->close();
|
|
echo "Finish !\n"
|
|
?>
|
Attachments
Issue Links
- blocks
-
MDEV-21168 Active XA transactions stop slave from working after backup was restored.
-
- Closed
-
-
MDEV-21854 xa commit 'xid' one phase for already prepared transaction must always error out
-
- Closed
-
- causes
-
MDEV-22733 XA PREPARE breaks MDL in pseudo_slave_mode=1
-
- In Progress
-
-
MDEV-26652 xa transactions binlogged in wrong order
-
- Closed
-
-
MDEV-26682 slave lock timeout with xa and gap locks
-
- Closed
-
-
MDEV-29410 abort-and-replay prepared XA transactions on the slave
-
- Open
-
-
MDEV-31949 slow parallel replication of user xa
-
- Stalled
-
- duplicates
-
MDEV-21304 kill session deletes XA prepared transaktion
-
- Closed
-
- is blocked by
-
MDEV-21659 XA rollback 'foreign_xid' is allowed inside active XA
-
- Closed
-
-
MDEV-21856 XID_t::formatID has to be contrained to 4 byte size
-
- Closed
-
- is duplicated by
-
MDEV-7974 backport fix for mysql bug#12161 (XA and binlog)
-
- Closed
-
- relates to
-
MDEV-15532 XA: Assertion `!log->same_pk' failed in row_log_table_apply_delete
-
- Closed
-
-
MDEV-21469 Implement crash-safe logging of the user XA
-
- Stalled
-
-
MDEV-21766 Forbid XID with empty 'gtrid'
-
- Closed
-
-
MDEV-21777 Implement crash-safe execution the user XA on binlog-less slave
-
- Open
-
-
MDEV-25055 XA ROLLBACK reports ER_XAER_NOTA for another connection's XA PREPARE
-
- Open
-
-
MDEV-29819 Shutdown unexpectedly executes XA ROLLBACK
-
- Open
-
-
MDEV-32813 read-only xa prepare may disappear upon server restart
-
- Open
-
-
MDEV-11675 Lag Free Alter On Slave
-
- Closed
-
-
MDEV-21168 Active XA transactions stop slave from working after backup was restored.
-
- Closed
-
-
MDEV-21602 CREATE TABLE…PRIMARY KEY…SELECT workaround causes DROP TABLE to ignore locks
-
- Closed
-
-
MDEV-21644 Assertion `thd->transaction.xid_state.is_explicit_XA()' failed in binlog_commit_flush_trx_cache
-
- Closed
-
-
MDEV-22445 Crash on HANDLER READ NEXT after XA PREPARE
-
- Closed
-
-
MDEV-22656 Document what rollback-xa mariabackup option does
-
- Closed
-
-
MDEV-25117 rpl.rpl_parallel_xa_same_xid failed in bb, sync_with_master failed:
-
- Open
-
-
MDEV-25616 Binlog event for XA COMMIT is generated without matching XA START, replication aborts
-
- Closed
-
-
MDEV-29642 Server Crash During XA Prepare Can Break Replication
-
- Closed
-
-
MDEV-32020 XA transaction replicates incorrectly, must be applied at XA COMMIT, not XA PREPARE
-
- Open
-
-
MDEV-33668 Adapt parallel slave's round-robin scheduling to XA events
-
- Closed
-
-
MDEV-35019 Provide a way to enable "rollback XA on disconnect" behavior we had before 10.5.2
-
- Stalled
-
- links to
Take-aways from discussions in Frankfurt:
detach_prepared_tx() is ok
he transaction remains prepared inside RocksDB.
MyRocks' Rdb_transaction object is de-associated from RocksDB transaction and
is destroyed. This is fine.
replace_native_transaction_in_thd is redundant
The idea behind this method is that it is needed on the slave. A slave worker
may run the following sequence of operations:
-- at this point, all actions by trx1 has been done
-- the only two actions that are possible are commit or rollback.
The problem with re-attaching is that Rdb_transaction has a quite a bit of context about the transaction outside the m_rocksdb_tx member.
If one just replaces the m_rocksdb_tx, we end up with a mismatch between Rdb_transaction members.
It is much better if the SQL layer uses the existing API and calls
engine_hton->(commit|rollback)_by_xid(...);
There was another argument: both InnoDB and MyRocks try to re-use their internal transaction object. and this is why replace_trx_in_thd saves it away. And this is how we end up with method signatures like this:
+innodb_replace_trx_in_thd(
+ THD* thd,
+ void* new_trx_arg,
+ void** ptr_trx_arg)
+{
My opinion is that this sort of caching should not be exposed through the storage engine API.