From 5fcde24091c01ce0f5941d434bd5761c07e51478 Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Fri, 24 Sep 2021 23:58:06 +0900 Subject: MDEV-26582 SIGSEGV in spider_db_bulk_insert and spider_db_connect and spider_db_before_query, and hang in "End of update loop" / "Reset for next command" query states Spider accesses a freed connection in ha_spider::end_bulk_insert() and results in SIGSEGV. The cause of the bug is that ha_spider::is_bulk_insert_exec_period() wrongly returns TRUE when the bulk insertion has not yet started. Spider decides whether it is during the bulk insertion or not by the value of insert_pos, but the variable is not reset in a case, and this result in the bug. --- .../mysql-test/spider/bugfix/r/mdev_26582.result | 11 +++++++++ .../mysql-test/spider/bugfix/t/mdev_26582.cnf | 2 ++ .../mysql-test/spider/bugfix/t/mdev_26582.test | 27 ++++++++++++++++++++++ storage/spider/spd_db_conn.cc | 10 ++++++++ 4 files changed, 50 insertions(+) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_26582.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_26582.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_26582.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26582.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26582.result new file mode 100644 index 00000000000..54a4fc44b48 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26582.result @@ -0,0 +1,11 @@ +# +# MDEV-26582 SIGSEGV in spider_db_bulk_insert and spider_db_connect and spider_db_before_query, and hang in "End of update loop" / "Reset for next command" query states +# +CREATE DATABASE IF NOT EXISTS auto_test_local; +USE auto_test_local; +CREATE TABLE t (i CHAR) ENGINE=SPIDER; +INSERT INTO t VALUES (0); +ERROR HY000: Unable to connect to foreign data source: localhost +INSERT t SELECT 1 ON DUPLICATE KEY UPDATE c=1; +ERROR 42S22: Unknown column 'c' in 'field list' +DROP DATABASE IF EXISTS auto_test_local; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26582.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_26582.cnf new file mode 100644 index 00000000000..b0853e32654 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26582.cnf @@ -0,0 +1,2 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26582.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26582.test new file mode 100644 index 00000000000..d0c57905915 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26582.test @@ -0,0 +1,27 @@ +--echo # +--echo # MDEV-26582 SIGSEGV in spider_db_bulk_insert and spider_db_connect and spider_db_before_query, and hang in "End of update loop" / "Reset for next command" query states +--echo # + +# NOTE: The bug does not reproduce if we import ../../t/test_init.inc instead. +--disable_query_log +--disable_result_log +--source ../../include/init_spider.inc +--enable_result_log +--enable_query_log + +CREATE DATABASE IF NOT EXISTS auto_test_local; +USE auto_test_local; + +CREATE TABLE t (i CHAR) ENGINE=SPIDER; +--error 1429 +INSERT INTO t VALUES (0); +--error 1054 +INSERT t SELECT 1 ON DUPLICATE KEY UPDATE c=1; + +DROP DATABASE IF EXISTS auto_test_local; + +--disable_query_log +--disable_result_log +--source ../../include/deinit_spider.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 22567d82bc1..d2cce0ba6d0 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -6661,7 +6661,11 @@ int spider_db_bulk_insert( #endif if ((error_num = spider->append_insert_values_sql_part( SPIDER_SQL_TYPE_INSERT_SQL))) + { + if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) + spider->set_insert_to_pos_sql(SPIDER_SQL_TYPE_INSERT_SQL); DBUG_RETURN(error_num); + } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) } if (spider->sql_kinds & SPIDER_SQL_KIND_HS) @@ -6681,6 +6685,8 @@ int spider_db_bulk_insert( if ((error_num = spider->append_insert_terminator_sql_part( SPIDER_SQL_TYPE_INSERT_SQL))) { + if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) + spider->set_insert_to_pos_sql(SPIDER_SQL_TYPE_INSERT_SQL); DBUG_RETURN(error_num); } #ifdef HA_CAN_BULK_ACCESS @@ -6715,6 +6721,8 @@ int spider_db_bulk_insert( if ((error_num = dbton_handler->set_sql_for_exec(sql_type, roop_count2))) { + if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) + spider->set_insert_to_pos_sql(SPIDER_SQL_TYPE_INSERT_SQL); if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type)) { SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); @@ -6744,6 +6752,8 @@ int spider_db_bulk_insert( conn->mta_conn_mutex_unlock_later = TRUE; if ((error_num = spider_db_set_names(spider, conn, roop_count2))) { + if (spider->sql_kinds & SPIDER_SQL_KIND_SQL) + spider->set_insert_to_pos_sql(SPIDER_SQL_TYPE_INSERT_SQL); DBUG_ASSERT(conn->mta_conn_mutex_lock_already); DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); conn->mta_conn_mutex_lock_already = FALSE; -- cgit v1.2.1