summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@mariadb.com>2016-06-27 18:21:00 -0400
committerNirbhay Choubey <nirbhay@mariadb.com>2016-06-27 18:21:00 -0400
commit90f222ea7dea4bebdb3ad93c4c1439e3ab08bbba (patch)
tree1d55a8e772d18d6857b8f81e5c354593c403a302 /sql/handler.cc
parentad3584bf728ad3ee48d99b81d8d14905524df4b8 (diff)
downloadmariadb-git-90f222ea7dea4bebdb3ad93c4c1439e3ab08bbba.tar.gz
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.
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc27
1 files changed, 22 insertions, 5 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 49e451e3836..147221abb97 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -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 */