codership / mysql-wsrep

wsrep API patch for MySQL server
Other
64 stars 34 forks source link

wsrep_retry_autocommit with stored procedure may cause error 2027 (Malformed packet) #313

Open AndriiNikitin opened 6 years ago

AndriiNikitin commented 6 years ago

mtr test below occasionally shows error 2027, unless wsrep_retry_autocommit=0

This raises question: should CALL command be considered as 'autocommit query' ? Since stored procedure may execute several commands, (including COMMIT) - my strong belief is that CALL shouldn't be considered as 'autocommit query' and thus shouldn't be retried without regard of wsrep_retry_autocommit configuration.

If for some reasons it will be decided that stored procedures should be re-tried, galera must (somehow) ensure that outgoing packets from Server do follow MySQL protocol and don't cause 2027 errors on retry.

Credit: https://jira.mariadb.org/browse/MDEV-4237 https://jira.mariadb.org/browse/MDEV-13770

mtr test

--source include/galera_cluster.inc
SET GLOBAL lock_wait_timeout = 2;
SET GLOBAL innodb_lock_wait_timeout = 1;

CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE OR REPLACE VIEW v1 AS SELECT pk FROM t1;
CREATE FUNCTION func1() RETURNS INTEGER RETURN 4;
CREATE FUNCTION func2() RETURNS INTEGER RETURN 4;
CREATE PROCEDURE proc1() SELECT func1() FROM v1;

--connect (con1,localhost,root,,test)
--connect (con2,localhost,root,,test)

--let $run = 100

while ($run)
{
  --connection con1
  --send
  CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT func2() AS pk FROM t1;
  --connection con2
  CALL proc1();
  --connection con1
  --reap
  --dec $run
}

drop table t1, v1;
drop function func1;
drop function func2;
drop procedure proc1;
~/mysql-wsrep$ ../mysql-wsrep-bld/mysql-test/mtr --repeat=10 --force MDEV-4237 --suite=galera 2>&1 | tee test.log | grep 2027
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
mysqltest: At line 26: query 'CALL proc1()' failed: 2027: Malformed packet
~/mysql-wsrep$ ../mysql-wsrep-bld/mysql-test/mtr --repeat=10 --force MDEV-4237 --suite=galera 2>&1 --mysqld=--wsrep-retry-autocommit=0 | tee test.log | grep 2027
~/mysql-wsrep$
temeo commented 5 years ago

The reason for the error is

#ifdef WITH_WSREP
  if (WSREP(thd) && thd->wsrep_retry_query)
  {
    WSREP_DEBUG("skipping select metadata");
    return FALSE;
  }
#endif /* WITH_WSREP */

in Query_result_send::send_result_set_metadata() which leaves THD::protocol metadata uninitialized. As a result garbage is returned to client.