mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-10235: Deadlock in CREATE TABLE .. AS SELECT .. if result set is empty in Galera
In CTAS, handlers get registered under statement transaction (st_transactions::stmt), while ha_fake_trx_id(), used by CTAS, looked under standard transaction (st_transactions::all) for registered handlers, and thus it failed to grab a fake transaction ID. As a result, with no valid transaction ID, wsrep commit failed with an error. ha_fake_trx_id() now looks for handlers registered under 'stmt' in case 'all' is empty. Also modified the logic to print warning only once if none of the registered handlers have fake_trx_id.
This commit is contained in:
@@ -68,4 +68,17 @@ CREATE TABLE `t2` (`c1` INT) ENGINE=INNODB SELECT * FROM t1;
|
||||
COMMIT;
|
||||
SET autocommit=1;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# MDEV-10235: Deadlock in CREATE TABLE ... AS SELECT .. if result set
|
||||
# is empty in Galera
|
||||
#
|
||||
CREATE TABLE t1(c1 INT) ENGINE=INNODB;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
CREATE TABLE t2 AS SELECT * FROM t1 WHERE c1=2;
|
||||
SELECT * FROM t1;
|
||||
c1
|
||||
1
|
||||
SELECT * FROM t2;
|
||||
c1
|
||||
DROP TABLE t1, t2;
|
||||
# End of tests
|
||||
|
||||
@@ -67,7 +67,6 @@ push @::global_suppressions,
|
||||
qr|WSREP: gcs_caused\(\) returned .*|,
|
||||
qr|WSREP: Protocol violation. JOIN message sender .* is not in state transfer \(SYNCED\). Message ignored.|,
|
||||
qr(WSREP: Action message in non-primary configuration from member [0-9]*),
|
||||
qr(WSREP: cannot get fake InnoDB transaction ID),
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,22 @@ SET autocommit=1;
|
||||
# Cleanup
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10235: Deadlock in CREATE TABLE ... AS SELECT .. if result set
|
||||
--echo # is empty in Galera
|
||||
--echo #
|
||||
--connection node_1
|
||||
CREATE TABLE t1(c1 INT) ENGINE=INNODB;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
CREATE TABLE t2 AS SELECT * FROM t1 WHERE c1=2;
|
||||
|
||||
--connection node_2
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
# Cleanup
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--source include/galera_end.inc
|
||||
--echo # End of tests
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
call mtr.add_suppression("WSREP: MariaDB Galera does not support binlog format.*");
|
||||
call mtr.add_suppression("WSREP: cannot get fake InnoDB transaction ID");
|
||||
call mtr.add_suppression("WSREP: Cannot get fake transaction ID from storage engine.");
|
||||
#
|
||||
# MDEV-4227: Galera server should stop crashing on setting binlog_format STATEMENT
|
||||
#
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
--source include/have_binlog_format_row.inc
|
||||
|
||||
call mtr.add_suppression("WSREP: MariaDB Galera does not support binlog format.*");
|
||||
call mtr.add_suppression("WSREP: cannot get fake InnoDB transaction ID");
|
||||
call mtr.add_suppression("WSREP: Cannot get fake transaction ID from storage engine.");
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-4227: Galera server should stop crashing on setting binlog_format STATEMENT
|
||||
|
||||
@@ -6104,25 +6104,42 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
|
||||
void ha_fake_trx_id(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("ha_fake_trx_id");
|
||||
|
||||
bool no_fake_trx_id= true;
|
||||
|
||||
if (!WSREP(thd))
|
||||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
THD_TRANS *trans= &thd->transaction.all;
|
||||
/* Try statement transaction if standard one is not set. */
|
||||
THD_TRANS *trans= (thd->transaction.all.ha_list) ? &thd->transaction.all :
|
||||
&thd->transaction.stmt;
|
||||
|
||||
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
|
||||
|
||||
for (; ha_info; ha_info= ha_info_next)
|
||||
{
|
||||
handlerton *hton= ha_info->ht();
|
||||
if (!hton->fake_trx_id)
|
||||
if (hton->fake_trx_id)
|
||||
{
|
||||
WSREP_WARN("cannot get fake InnoDB transaction ID");
|
||||
}
|
||||
else
|
||||
hton->fake_trx_id(hton, thd);
|
||||
|
||||
/* Got a fake trx id. */
|
||||
no_fake_trx_id= false;
|
||||
|
||||
/*
|
||||
We need transaction ID from just one storage engine providing
|
||||
fake_trx_id (which will most likely be the case).
|
||||
*/
|
||||
break;
|
||||
}
|
||||
ha_info_next= ha_info->next();
|
||||
}
|
||||
|
||||
if (unlikely(no_fake_trx_id))
|
||||
WSREP_WARN("Cannot get fake transaction ID from storage engine.");
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
Reference in New Issue
Block a user