Commit 52a5b16b authored by Yuchen Pei's avatar Yuchen Pei

MDEV-29963 MDEV-31357 Spider should clear its lock lists when locking fails

Spider populates its lock lists (a hash) in store_lock(), and normally
clears them in the actual lock_tables(). However, if lock_tables()
fails, there's no reset_lock() method for storage engine handlers,
which can cause bad things to happen. For example, if one of the table
involved is dropped and recreated, or simply TRUNCATEd, when executing
LOCK TABLES again, the lock lists would be queried again in
store_lock(), which could cause access to freed space associated with
the dropped table.
parent 17839657
#
# MDEV-29963 SIGSEGV in spider_db_mbase::append_lock_tables on LOCK TABLES
#
for master_1
for child2
for child3
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (a INT) ENGINE=Spider;
CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
LOCK TABLES t AS a READ,t2 AS b LOW_PRIORITY WRITE,t2 AS c WRITE;
ERROR HY000: Unable to connect to foreign data source: localhost
DROP TABLE t2;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
LOCK TABLES t2 WRITE;
ERROR HY000: Unable to connect to foreign data source: localhost
DROP TABLE t2,t;
CREATE TABLE t (a INT);
CREATE TABLE t1 (a INT) ENGINE=Spider;
CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
LOCK TABLES t1 READ, t2 WRITE;
ERROR HY000: Unable to connect to foreign data source: localhost
DROP TABLE t2;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
LOCK TABLES t2 WRITE;
UNLOCK TABLES;
DROP TABLE t, t1, t2;
CREATE TABLE t1 (c INT) ENGINE=Spider;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT="WRAPPER 'mysql',srv 'srv',TABLE 't1'";
LOCK TABLES t1 WRITE,t2 WRITE;
ERROR HY000: Unable to connect to foreign data source: localhost
TRUNCATE t2;
ERROR HY000: Unable to connect to foreign data source: localhost
LOCK TABLES t2 AS o WRITE;
ERROR HY000: Unable to connect to foreign data source: localhost
drop table t1, t2;
drop server srv;
for master_1
for child2
for child3
#
# end of test mdev_29963
#
--echo #
--echo # MDEV-29963 SIGSEGV in spider_db_mbase::append_lock_tables on LOCK TABLES
--echo #
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (a INT) ENGINE=Spider;
CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
LOCK TABLES t AS a READ,t2 AS b LOW_PRIORITY WRITE,t2 AS c WRITE;
DROP TABLE t2;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
LOCK TABLES t2 WRITE;
DROP TABLE t2,t;
# A less complex scenario
CREATE TABLE t (a INT);
CREATE TABLE t1 (a INT) ENGINE=Spider;
CREATE TABLE t2 (b INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
LOCK TABLES t1 READ, t2 WRITE;
DROP TABLE t2;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
LOCK TABLES t2 WRITE;
UNLOCK TABLES;
DROP TABLE t, t1, t2;
# MDEV-31357
CREATE TABLE t1 (c INT) ENGINE=Spider;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT="WRAPPER 'mysql',srv 'srv',TABLE 't1'";
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
LOCK TABLES t1 WRITE,t2 WRITE;
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
TRUNCATE t2;
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
LOCK TABLES t2 AS o WRITE;
drop table t1, t2;
drop server srv;
--disable_query_log
--disable_result_log
--source ../../t/test_deinit.inc
--enable_result_log
--enable_query_log
--echo #
--echo # end of test mdev_29963
--echo #
......@@ -3462,6 +3462,14 @@ int spider_rollback(
trx->bulk_access_conn_first = NULL;
#endif
/* In case the rollback happens due to failure of LOCK TABLE, we
need to clear the list of tables to lock. */
for (uint i= 0; i < trx->trx_conn_hash.records; i++)
{
conn= (SPIDER_CONN *) my_hash_element(&trx->trx_conn_hash, i);
conn->db_conn->reset_lock_table_hash();
}
if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (trx->trx_start)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment