diff options
-rw-r--r-- | mysql-test/suite/funcs_1/t/myisam_views-big.test | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb_gis/t/multi_pk.test | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb_gis/t/rtree_purge.test | 2 | ||||
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 4 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 20 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 19 | ||||
-rw-r--r-- | storage/spider/ha_spider.cc | 86 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/disabled.def | 1 | ||||
-rw-r--r-- | storage/spider/spd_trx.cc | 151 |
9 files changed, 109 insertions, 178 deletions
diff --git a/mysql-test/suite/funcs_1/t/myisam_views-big.test b/mysql-test/suite/funcs_1/t/myisam_views-big.test index bf499ee789a..60fe1b8eaba 100644 --- a/mysql-test/suite/funcs_1/t/myisam_views-big.test +++ b/mysql-test/suite/funcs_1/t/myisam_views-big.test @@ -4,6 +4,8 @@ # because of a pair of slow Solaris Sparc machines in pb2, # this test is marked as big: --source include/big_test.inc +# This test often times out with MSAN +--source include/not_msan.inc # MyISAM tables should be used # diff --git a/mysql-test/suite/innodb_gis/t/multi_pk.test b/mysql-test/suite/innodb_gis/t/multi_pk.test index c90f794fe15..1be919d165a 100644 --- a/mysql-test/suite/innodb_gis/t/multi_pk.test +++ b/mysql-test/suite/innodb_gis/t/multi_pk.test @@ -8,6 +8,8 @@ --source include/have_debug.inc --source include/big_test.inc --source include/not_valgrind.inc +# This test often times out with MSAN +--source include/not_msan.inc # Create table with R-tree index. create table t1 (c1 int, c2 varchar(255), c3 geometry not null, primary key(c1, c2), spatial index (c3))engine=innodb; diff --git a/mysql-test/suite/innodb_gis/t/rtree_purge.test b/mysql-test/suite/innodb_gis/t/rtree_purge.test index 60ecbe2e53a..fc5ce2e14bc 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_purge.test +++ b/mysql-test/suite/innodb_gis/t/rtree_purge.test @@ -3,6 +3,8 @@ --source include/innodb_page_size.inc --source include/have_sequence.inc --source include/not_valgrind.inc +# This test often times out with MSAN +--source include/not_msan.inc SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 0bd5467cbfa..616d5764181 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1342,7 +1342,7 @@ inline bool fil_space_t::acquire_if_not_stopped() return true; if (UNIV_UNLIKELY(n & STOPPING)) return false; - return UNIV_LIKELY(!(n & CLOSING)) || prepare(true); + return UNIV_LIKELY(!(n & CLOSING)) || prepare_acquired(); } bool fil_crypt_must_default_encrypt() @@ -1458,7 +1458,7 @@ space_list_t::iterator fil_space_t::next(space_list_t::iterator space, const uint32_t n= space->acquire_low(); if (UNIV_LIKELY(!(n & (STOPPING | CLOSING)))) break; - if (!(n & STOPPING) && space->prepare(true)) + if (!(n & STOPPING) && space->prepare_acquired()) break; } } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 316920d3fe3..95c9987ae9d 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -648,11 +648,9 @@ fil_space_extend_must_retry( } /** @return whether the file is usable for io() */ -ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex) +ATTRIBUTE_COLD bool fil_space_t::prepare_acquired() { ut_ad(referenced()); - if (!have_mutex) - mysql_mutex_lock(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex); fil_node_t *node= UT_LIST_GET_LAST(chain); ut_ad(!id || purpose == FIL_TYPE_TEMPORARY || @@ -697,8 +695,16 @@ ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex) clear: clear_closing(); - if (!have_mutex) - mysql_mutex_unlock(&fil_system.mutex); + return is_open; +} + +/** @return whether the file is usable for io() */ +ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() +{ + mysql_mutex_lock(&fil_system.mutex); + const auto flags= acquire_low() & (STOPPING | CLOSING); + const bool is_open= !flags || (flags == CLOSING && prepare_acquired()); + mysql_mutex_unlock(&fil_system.mutex); return is_open; } @@ -1441,13 +1447,13 @@ fil_space_t *fil_space_t::get(ulint id) mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); const uint32_t n= space ? space->acquire_low() : 0; - mysql_mutex_unlock(&fil_system.mutex); if (n & STOPPING) space= nullptr; - else if ((n & CLOSING) && !space->prepare()) + else if ((n & CLOSING) && !space->prepare_acquired()) space= nullptr; + mysql_mutex_unlock(&fil_system.mutex); return space; } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index fadaf36f83b..b9db9afdb5e 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -538,15 +538,16 @@ public: private: MY_ATTRIBUTE((warn_unused_result)) - /** Try to acquire a tablespace reference. - @return the old reference count (if STOPPING is set, it was not acquired) */ - uint32_t acquire_low() + /** Try to acquire a tablespace reference (increment referenced()). + @param avoid when these flags are set, nothing will be acquired + @return the old reference count */ + uint32_t acquire_low(uint32_t avoid= STOPPING) { uint32_t n= 0; while (!n_pending.compare_exchange_strong(n, n + 1, std::memory_order_acquire, std::memory_order_relaxed) && - !(n & STOPPING)); + !(n & avoid)); return n; } public: @@ -560,10 +561,8 @@ public: @return whether the file is usable */ bool acquire() { - uint32_t n= acquire_low(); - if (UNIV_LIKELY(!(n & (STOPPING | CLOSING)))) - return true; - return UNIV_LIKELY(!(n & STOPPING)) && prepare(); + const auto flags= acquire_low(STOPPING | CLOSING) & (STOPPING | CLOSING); + return UNIV_LIKELY(!flags) || (flags == CLOSING && acquire_and_prepare()); } /** Acquire another tablespace reference for I/O. */ @@ -1092,7 +1091,9 @@ public: private: /** @return whether the file is usable for io() */ - ATTRIBUTE_COLD bool prepare(bool have_mutex= false); + ATTRIBUTE_COLD bool prepare_acquired(); + /** @return whether the file is usable for io() */ + ATTRIBUTE_COLD bool acquire_and_prepare(); #endif /*!UNIV_INNOCHECKSUM */ }; diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 2155861c61e..712397ffb92 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -1180,10 +1180,8 @@ int ha_spider::external_lock( backup_error_status(); DBUG_ENTER("ha_spider::external_lock"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider lock_type=%x", lock_type)); - DBUG_PRINT("info", ("spider sql_command=%d", thd_sql_command(thd))); + /* Beginning of wide_handler setup */ if (wide_handler->stage == SPD_HND_STAGE_EXTERNAL_LOCK) { /* Only the stage executor deals with table locks. */ @@ -1194,7 +1192,7 @@ int ha_spider::external_lock( } else { - /* Update the stage executor when the stage changes */ + /* Update the stage executor when the stage changes. */ wide_handler->stage= SPD_HND_STAGE_EXTERNAL_LOCK; wide_handler->stage_executor= this; } @@ -1203,35 +1201,30 @@ int ha_spider::external_lock( wide_handler->external_lock_type= lock_type; wide_handler->sql_command = thd_sql_command(thd); - /* We treat BEGIN as if UNLOCK TABLE. */ - if (wide_handler->sql_command == SQLCOM_BEGIN) - { - wide_handler->sql_command = SQLCOM_UNLOCK_TABLES; - } - if (lock_type == F_UNLCK && - wide_handler->sql_command != SQLCOM_UNLOCK_TABLES) - { - DBUG_RETURN(0); - } - - trx = spider_get_trx(thd, TRUE, &error_num); + trx= spider_get_trx(thd, TRUE, &error_num); if (error_num) { DBUG_RETURN(error_num); } - wide_handler->trx = trx; + wide_handler->trx= trx; + /* End of wide_handler setup */ - /* Question: Why the following if block is necessary? Why here? */ if (store_error_num) { DBUG_RETURN(store_error_num); } - DBUG_ASSERT(wide_handler->sql_command != SQLCOM_RENAME_TABLE && - wide_handler->sql_command != SQLCOM_DROP_DB); + /* We treat BEGIN as if UNLOCK TABLE. */ + if (wide_handler->sql_command == SQLCOM_BEGIN) + { + wide_handler->sql_command = SQLCOM_UNLOCK_TABLES; + } + const uint sql_command= wide_handler->sql_command; + + DBUG_ASSERT(sql_command != SQLCOM_RENAME_TABLE && + sql_command != SQLCOM_DROP_DB); - if (wide_handler->sql_command == SQLCOM_DROP_TABLE || - wide_handler->sql_command == SQLCOM_ALTER_TABLE) + if (sql_command == SQLCOM_DROP_TABLE || sql_command == SQLCOM_ALTER_TABLE) { if (trx->locked_connections) { @@ -1242,44 +1235,41 @@ int ha_spider::external_lock( DBUG_RETURN(0); } - if (lock_type != F_UNLCK) + if (lock_type == F_UNLCK) + { + if (sql_command != SQLCOM_UNLOCK_TABLES) + { + DBUG_RETURN(0); /* Unlock remote tables only by UNLOCK TABLES. */ + } + if (!trx->locked_connections) + { + DBUG_RETURN(0); /* No remote table actually locked by Spider */ + } + } + else { if (unlikely((error_num= spider_internal_start_trx(this)))) { DBUG_RETURN(error_num); } - if (wide_handler->sql_command != SQLCOM_SELECT && - wide_handler->sql_command != SQLCOM_HA_READ) + if (sql_command != SQLCOM_SELECT && sql_command != SQLCOM_HA_READ) { trx->updated_in_this_trx= TRUE; - DBUG_PRINT("info", ("spider trx->updated_in_this_trx=TRUE")); + } + if (!wide_handler->lock_table_type) + { + DBUG_RETURN(0); /* No need to actually lock remote tables. */ } } - if (wide_handler->lock_table_type > 0 || - wide_handler->sql_command == SQLCOM_UNLOCK_TABLES) + if (!partition_handler || !partition_handler->handlers) { - if (wide_handler->sql_command == SQLCOM_UNLOCK_TABLES) - { - /* lock tables does not call reset() */ - /* unlock tables does not call store_lock() */ - wide_handler->lock_table_type = 0; - } + DBUG_RETURN(lock_tables()); /* Non-partitioned table */ + } - /* lock/unlock tables */ - if (partition_handler && partition_handler->handlers) - { - for (uint roop_count= 0; roop_count < partition_handler->no_parts; - ++roop_count) - { - if (unlikely((error_num = - partition_handler->handlers[roop_count]->lock_tables()))) - { - DBUG_RETURN(error_num); - } - } - } - else if (unlikely((error_num= lock_tables()))) + for (uint i= 0; i < partition_handler->no_parts; ++i) + { + if (unlikely((error_num= partition_handler->handlers[i]->lock_tables()))) { DBUG_RETURN(error_num); } diff --git a/storage/spider/mysql-test/spider/bugfix/disabled.def b/storage/spider/mysql-test/spider/bugfix/disabled.def index 68de2b6bfde..e19ea07b76b 100644 --- a/storage/spider/mysql-test/spider/bugfix/disabled.def +++ b/storage/spider/mysql-test/spider/bugfix/disabled.def @@ -1,2 +1 @@ wait_timeout : MDEV-26045 -mdev_27239 : failed with ASAN build diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index c5095e7ff55..e832c2bc450 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -93,128 +93,51 @@ uchar *spider_trx_ha_get_key( DBUG_RETURN((uchar*) trx_ha->table_name); } -int spider_free_trx_conn( - SPIDER_TRX *trx, - bool trx_free -) { - int roop_count; +/* + Try to free the connections held by the given transaction. +*/ +int spider_free_trx_conn(SPIDER_TRX *trx, bool trx_free) +{ + int loop_count= 0; SPIDER_CONN *conn; + HASH *conn_hash= &trx->trx_conn_hash; + DBUG_ENTER("spider_free_trx_conn"); - roop_count = 0; - if ( - trx_free || - spider_param_conn_recycle_mode(trx->thd) != 2 - ) { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash, - roop_count))) - { - spider_conn_clear_queue_at_commit(conn); - if (conn->table_lock) - { - DBUG_ASSERT(!trx_free); - roop_count++; - } else - spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &roop_count); - } - trx->trx_conn_adjustment++; - } else { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash, - roop_count))) - { - spider_conn_clear_queue_at_commit(conn); - if (conn->table_lock) - { - DBUG_ASSERT(!trx_free); - } else - conn->error_mode = 1; - roop_count++; - } - } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - roop_count = 0; - if ( - trx_free || - spider_param_hs_r_conn_recycle_mode(trx->thd) != 2 - ) { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_hs_r_conn_hash, - roop_count))) - { - if (conn->table_lock) - { - DBUG_ASSERT(!trx_free); - roop_count++; - } else - spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &roop_count); - } - trx->trx_hs_r_conn_adjustment++; - } else { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_hs_r_conn_hash, - roop_count))) - { - if (conn->table_lock) - { - DBUG_ASSERT(!trx_free); - } else - conn->error_mode = 1; - roop_count++; - } + DBUG_ASSERT(!trx_free || !trx->locked_connections); + + /* Clear the connection queues in any case. */ + while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count))) + { + spider_conn_clear_queue_at_commit(conn); + loop_count++; } - roop_count = 0; - if ( - trx_free || - spider_param_hs_w_conn_recycle_mode(trx->thd) != 2 - ) { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_hs_w_conn_hash, - roop_count))) - { - if (conn->table_lock) - { - DBUG_ASSERT(!trx_free); - roop_count++; - } else - spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &roop_count); - } - trx->trx_hs_w_conn_adjustment++; - } else { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_hs_w_conn_hash, - roop_count))) + + if (trx_free || spider_param_conn_recycle_mode(trx->thd) != 2) + { + /* Free connections only when no connection is locked. */ + if (!trx->locked_connections) { - if (conn->table_lock) + loop_count= 0; + while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count))) { - DBUG_ASSERT(!trx_free); - } else - conn->error_mode = 1; - roop_count++; + spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &loop_count); + } } + trx->trx_conn_adjustment++; + + DBUG_RETURN(0); } -#endif -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if (trx_free) + + loop_count= 0; + while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count))) { - while ((conn = (SPIDER_CONN*) my_hash_element( - &trx->trx_direct_hs_r_conn_hash, 0))) - { -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&trx->trx_direct_hs_r_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&trx->trx_direct_hs_r_conn_hash, (uchar*) conn); -#endif - spider_free_conn(conn); - } - while ((conn = (SPIDER_CONN*) my_hash_element( - &trx->trx_direct_hs_w_conn_hash, 0))) + if (!conn->table_lock) { -#ifdef HASH_UPDATE_WITH_HASH_VALUE - my_hash_delete_with_hash_value(&trx->trx_direct_hs_w_conn_hash, - conn->conn_key_hash_value, (uchar*) conn); -#else - my_hash_delete(&trx->trx_direct_hs_w_conn_hash, (uchar*) conn); -#endif - spider_free_conn(conn); + conn->error_mode= 1; } + loop_count++; } -#endif + DBUG_RETURN(0); } @@ -3475,6 +3398,12 @@ int spider_commit( trx->bulk_access_conn_first = NULL; #endif + /* + We do (almost) nothing if the following two conditions are both met: + + * This is just the end of a statement, not an explicit commit. + * The autocommit is OFF or we are in an explicit transaction. + */ if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (trx->trx_start) |