Skip to content
Permalink
Browse files

Wsrep crash caused by COM_CHANGE_USER, COM_RESET_CONNECTION (#1358)

COM_CHANGE_USER and COM_RESET_CONNECTION commands cause
THD::cleanup() to be called in the middle of command handling.
This causes wsrep client_state sanity checks to fail.

As a fix, temporarily close wsrep client_state before THD::change_user()
is called when handling COM_CHANGE_USER and COM_RESET_CONNECTION,
and restore the state after THD::change_user() returns.

This commit also updates wsrep-lib to version which removes
exception usage in wsrep client_state sanity checks.
  • Loading branch information...
temeo authored and janlindstrom committed Jul 15, 2019
1 parent a0230bc commit 61cc932781cae3864be8f964c3893cfc3f059ff6
@@ -0,0 +1,14 @@
connection node_2;
connection node_1;
connection node_1;
CREATE USER user1;
CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1;
disconnect node_1a;
connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1;
START TRANSACTION;
INSERT INTO t1 VALUES (1);
disconnect node_1a;
connection node_1;
DROP TABLE t1;
DROP USER user1;
@@ -0,0 +1,29 @@
#
# Check that change user works with Galera
#

--source include/galera_cluster.inc
--source include/have_innodb.inc

--connection node_1
CREATE USER user1;
CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;

# Change user in idle connection
--connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1
change_user 'user1';
reset_connection;
--disconnect node_1a

# Change user with transaction open
--connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1
START TRANSACTION;
INSERT INTO t1 VALUES (1);
change_user 'user1';
reset_connection;
--disconnect node_1a

--connection node_1
DROP TABLE t1;
DROP USER user1;

@@ -1660,8 +1660,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_RESET_CONNECTION:
{
thd->status_var.com_other++;
#ifdef WITH_WSREP
wsrep_after_command_ignore_result(thd);
wsrep_close(thd);
#endif /* WITH_WSREP */
thd->change_user();
thd->clear_error(); // if errors from rollback
#ifdef WITH_WSREP
wsrep_open(thd);
wsrep_before_command(thd);
#endif /* WITH_WSREP */
/* Restore original charset from client authentication packet.*/
if(thd->org_charset)
thd->update_charset(thd->org_charset,thd->org_charset,thd->org_charset);
@@ -1673,7 +1681,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
int auth_rc;
status_var_increment(thd->status_var.com_other);

#ifdef WITH_WSREP
wsrep_after_command_ignore_result(thd);
wsrep_close(thd);
#endif /* WITH_WSREP */
thd->change_user();
#ifdef WITH_WSREP
wsrep_open(thd);
wsrep_before_command(thd);
#endif /* WITH_WSREP */
thd->clear_error(); // if errors from rollback

/* acl_authenticate() takes the data from net->read_pos */

0 comments on commit 61cc932

Please sign in to comment.
You can’t perform that action at this time.