From a68b9dd9932aeaf4021675c760bf753d803a326b Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Thu, 12 Jan 2023 13:41:49 +1100 Subject: MDEV-26541 Make UBSAN builds work with spider again. When built with ubsan and trying to load the spider plugin, the hidden visibility of mysqld compiling flag causes ha_spider.so to be missing the symbol ha_partition. This commit fixes that, as well as some memcpy null pointer issues when built with ubsan. Signed-off-by: Yuchen Pei --- .../mysql-test/spider/bugfix/r/mdev_26541.result | 20 ++ .../mysql-test/spider/bugfix/t/mdev_26541.test | 40 ++++ storage/spider/spd_conn.cc | 19 +- storage/spider/spd_trx.cc | 234 ++++++++++++--------- 4 files changed, 206 insertions(+), 107 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test (limited to 'storage/spider') diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result new file mode 100644 index 00000000000..b2edaff6918 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result @@ -0,0 +1,20 @@ +# +# MDEV-26541 Undefined symbol: _ZTI12ha_partition when attempting to use ha_spider.so in UBSAN builds +# +INSTALL PLUGIN spider SONAME 'ha_spider.so'; +DROP FUNCTION spider_flush_table_mon_cache; +DROP FUNCTION spider_copy_tables; +DROP FUNCTION spider_ping_table; +DROP FUNCTION spider_bg_direct_sql; +DROP FUNCTION spider_direct_sql; +UNINSTALL PLUGIN spider_alloc_mem; +UNINSTALL PLUGIN spider; +DROP TABLE IF EXISTS mysql.spider_xa; +DROP TABLE IF EXISTS mysql.spider_xa_member; +DROP TABLE IF EXISTS mysql.spider_xa_failed_log; +DROP TABLE IF EXISTS mysql.spider_tables; +DROP TABLE IF EXISTS mysql.spider_link_mon_servers; +DROP TABLE IF EXISTS mysql.spider_link_failed_log; +DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; +DROP TABLE IF EXISTS mysql.spider_table_sts; +DROP TABLE IF EXISTS mysql.spider_table_crd; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test new file mode 100644 index 00000000000..ffd99390748 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test @@ -0,0 +1,40 @@ +--echo # +--echo # MDEV-26541 Undefined symbol: _ZTI12ha_partition when attempting to use ha_spider.so in UBSAN builds +--echo # + +if (`select not(count(*)) from information_schema.system_variables where variable_name='have_sanitizer' and global_value="UBSAN"`) +{ +--skip test needs to be run with UBSAN +} + +# init spider + +INSTALL PLUGIN spider SONAME 'ha_spider.so'; + +let $PLUGIN_NAME= spider_flush_table_mon_cache; +let $PLUGIN_EXIST= + `SELECT COUNT(*) FROM mysql.func WHERE name = '$PLUGIN_NAME'`; +while (!$PLUGIN_EXIST) +{ + let $PLUGIN_EXIST= + `SELECT COUNT(*) FROM mysql.func WHERE name = '$PLUGIN_NAME'`; +} + +# deinit spider + +DROP FUNCTION spider_flush_table_mon_cache; +DROP FUNCTION spider_copy_tables; +DROP FUNCTION spider_ping_table; +DROP FUNCTION spider_bg_direct_sql; +DROP FUNCTION spider_direct_sql; +UNINSTALL PLUGIN spider_alloc_mem; +UNINSTALL PLUGIN spider; +DROP TABLE IF EXISTS mysql.spider_xa; +DROP TABLE IF EXISTS mysql.spider_xa_member; +DROP TABLE IF EXISTS mysql.spider_xa_failed_log; +DROP TABLE IF EXISTS mysql.spider_tables; +DROP TABLE IF EXISTS mysql.spider_link_mon_servers; +DROP TABLE IF EXISTS mysql.spider_link_failed_log; +DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; +DROP TABLE IF EXISTS mysql.spider_table_sts; +DROP TABLE IF EXISTS mysql.spider_table_crd; diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index cef4ba04eb1..1faa65d0db5 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -518,18 +518,25 @@ SPIDER_CONN *spider_create_conn( conn->tgt_host = tmp_host; memcpy(conn->tgt_host, share->tgt_hosts[link_idx], share->tgt_hosts_lengths[link_idx]); + conn->tgt_username_length = share->tgt_usernames_lengths[link_idx]; conn->tgt_username = tmp_username; - memcpy(conn->tgt_username, share->tgt_usernames[link_idx], - share->tgt_usernames_lengths[link_idx]); + if (conn->tgt_username_length) + memcpy(conn->tgt_username, share->tgt_usernames[link_idx], + share->tgt_usernames_lengths[link_idx]); + conn->tgt_password_length = share->tgt_passwords_lengths[link_idx]; conn->tgt_password = tmp_password; - memcpy(conn->tgt_password, share->tgt_passwords[link_idx], - share->tgt_passwords_lengths[link_idx]); + if (conn->tgt_password_length) + memcpy(conn->tgt_password, share->tgt_passwords[link_idx], + share->tgt_passwords_lengths[link_idx]); + conn->tgt_socket_length = share->tgt_sockets_lengths[link_idx]; conn->tgt_socket = tmp_socket; - memcpy(conn->tgt_socket, share->tgt_sockets[link_idx], - share->tgt_sockets_lengths[link_idx]); + if (conn->tgt_socket_length) + memcpy(conn->tgt_socket, share->tgt_sockets[link_idx], + share->tgt_sockets_lengths[link_idx]); + conn->tgt_wrapper_length = share->tgt_wrappers_lengths[link_idx]; conn->tgt_wrapper = tmp_wrapper; memcpy(conn->tgt_wrapper, share->tgt_wrappers[link_idx], diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index 4f8296f1d01..b0b1e9c36bd 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -682,112 +682,144 @@ int spider_create_trx_alter_table( alter_table->tmp_tgt_default_groups_lengths = tmp_tgt_default_groups_lengths; alter_table->tmp_static_link_ids_lengths = tmp_static_link_ids_lengths; + size_t len; for(roop_count = 0; roop_count < (int) share->all_link_count; roop_count++) { - tmp_server_names[roop_count] = tmp_server_names_char; - memcpy(tmp_server_names_char, - share_alter->tmp_server_names[roop_count], - sizeof(char) * share_alter->tmp_server_names_lengths[roop_count]); - tmp_server_names_char += - share_alter->tmp_server_names_lengths[roop_count] + 1; - - tmp_tgt_table_names[roop_count] = tmp_tgt_table_names_char; - memcpy(tmp_tgt_table_names_char, - share_alter->tmp_tgt_table_names[roop_count], - sizeof(char) * share_alter->tmp_tgt_table_names_lengths[roop_count]); - tmp_tgt_table_names_char += - share_alter->tmp_tgt_table_names_lengths[roop_count] + 1; - - tmp_tgt_dbs[roop_count] = tmp_tgt_dbs_char; - memcpy(tmp_tgt_dbs_char, share_alter->tmp_tgt_dbs[roop_count], - sizeof(char) * share_alter->tmp_tgt_dbs_lengths[roop_count]); - tmp_tgt_dbs_char += - share_alter->tmp_tgt_dbs_lengths[roop_count] + 1; - - tmp_tgt_hosts[roop_count] = tmp_tgt_hosts_char; - memcpy(tmp_tgt_hosts_char, share_alter->tmp_tgt_hosts[roop_count], - sizeof(char) * share_alter->tmp_tgt_hosts_lengths[roop_count]); - tmp_tgt_hosts_char += - share_alter->tmp_tgt_hosts_lengths[roop_count] + 1; - - tmp_tgt_usernames[roop_count] = tmp_tgt_usernames_char; - memcpy(tmp_tgt_usernames_char, share_alter->tmp_tgt_usernames[roop_count], - sizeof(char) * share_alter->tmp_tgt_usernames_lengths[roop_count]); - tmp_tgt_usernames_char += - share_alter->tmp_tgt_usernames_lengths[roop_count] + 1; - - tmp_tgt_passwords[roop_count] = tmp_tgt_passwords_char; - memcpy(tmp_tgt_passwords_char, share_alter->tmp_tgt_passwords[roop_count], - sizeof(char) * share_alter->tmp_tgt_passwords_lengths[roop_count]); - tmp_tgt_passwords_char += - share_alter->tmp_tgt_passwords_lengths[roop_count] + 1; - - tmp_tgt_sockets[roop_count] = tmp_tgt_sockets_char; - memcpy(tmp_tgt_sockets_char, share_alter->tmp_tgt_sockets[roop_count], - sizeof(char) * share_alter->tmp_tgt_sockets_lengths[roop_count]); - tmp_tgt_sockets_char += - share_alter->tmp_tgt_sockets_lengths[roop_count] + 1; - - tmp_tgt_wrappers[roop_count] = tmp_tgt_wrappers_char; - memcpy(tmp_tgt_wrappers_char, share_alter->tmp_tgt_wrappers[roop_count], - sizeof(char) * share_alter->tmp_tgt_wrappers_lengths[roop_count]); - tmp_tgt_wrappers_char += - share_alter->tmp_tgt_wrappers_lengths[roop_count] + 1; - - tmp_tgt_ssl_cas[roop_count] = tmp_tgt_ssl_cas_char; - memcpy(tmp_tgt_ssl_cas_char, share_alter->tmp_tgt_ssl_cas[roop_count], - sizeof(char) * share_alter->tmp_tgt_ssl_cas_lengths[roop_count]); - tmp_tgt_ssl_cas_char += - share_alter->tmp_tgt_ssl_cas_lengths[roop_count] + 1; - - tmp_tgt_ssl_capaths[roop_count] = tmp_tgt_ssl_capaths_char; - memcpy(tmp_tgt_ssl_capaths_char, - share_alter->tmp_tgt_ssl_capaths[roop_count], - sizeof(char) * share_alter->tmp_tgt_ssl_capaths_lengths[roop_count]); - tmp_tgt_ssl_capaths_char += - share_alter->tmp_tgt_ssl_capaths_lengths[roop_count] + 1; - - tmp_tgt_ssl_certs[roop_count] = tmp_tgt_ssl_certs_char; - memcpy(tmp_tgt_ssl_certs_char, share_alter->tmp_tgt_ssl_certs[roop_count], - sizeof(char) * share_alter->tmp_tgt_ssl_certs_lengths[roop_count]); - tmp_tgt_ssl_certs_char += - share_alter->tmp_tgt_ssl_certs_lengths[roop_count] + 1; - - tmp_tgt_ssl_ciphers[roop_count] = tmp_tgt_ssl_ciphers_char; - memcpy(tmp_tgt_ssl_ciphers_char, - share_alter->tmp_tgt_ssl_ciphers[roop_count], - sizeof(char) * share_alter->tmp_tgt_ssl_ciphers_lengths[roop_count]); - tmp_tgt_ssl_ciphers_char += - share_alter->tmp_tgt_ssl_ciphers_lengths[roop_count] + 1; - - tmp_tgt_ssl_keys[roop_count] = tmp_tgt_ssl_keys_char; - memcpy(tmp_tgt_ssl_keys_char, share_alter->tmp_tgt_ssl_keys[roop_count], - sizeof(char) * share_alter->tmp_tgt_ssl_keys_lengths[roop_count]); - tmp_tgt_ssl_keys_char += - share_alter->tmp_tgt_ssl_keys_lengths[roop_count] + 1; - - tmp_tgt_default_files[roop_count] = tmp_tgt_default_files_char; - memcpy(tmp_tgt_default_files_char, - share_alter->tmp_tgt_default_files[roop_count], - sizeof(char) * share_alter->tmp_tgt_default_files_lengths[roop_count]); - tmp_tgt_default_files_char += - share_alter->tmp_tgt_default_files_lengths[roop_count] + 1; - - tmp_tgt_default_groups[roop_count] = tmp_tgt_default_groups_char; - memcpy(tmp_tgt_default_groups_char, - share_alter->tmp_tgt_default_groups[roop_count], - sizeof(char) * share_alter->tmp_tgt_default_groups_lengths[roop_count]); - tmp_tgt_default_groups_char += - share_alter->tmp_tgt_default_groups_lengths[roop_count] + 1; - - if (share_alter->tmp_static_link_ids[roop_count]) + if ((len= + sizeof(char) * share_alter->tmp_server_names_lengths[roop_count])) + { + tmp_server_names[roop_count]= tmp_server_names_char; + memcpy(tmp_server_names_char, share_alter->tmp_server_names[roop_count], + len); + tmp_server_names_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_table_names_lengths[roop_count])) + { + tmp_tgt_table_names[roop_count]= tmp_tgt_table_names_char; + memcpy(tmp_tgt_table_names_char, + share_alter->tmp_tgt_table_names[roop_count], len); + tmp_tgt_table_names_char+= len + 1; + } + + if ((len= sizeof(char) * share_alter->tmp_tgt_dbs_lengths[roop_count])) + { + tmp_tgt_dbs[roop_count]= tmp_tgt_dbs_char; + memcpy(tmp_tgt_dbs_char, share_alter->tmp_tgt_dbs[roop_count], len); + tmp_tgt_dbs_char+= len + 1; + } + + if ((len= sizeof(char) * share_alter->tmp_tgt_hosts_lengths[roop_count])) + { + tmp_tgt_hosts[roop_count]= tmp_tgt_hosts_char; + memcpy(tmp_tgt_hosts_char, share_alter->tmp_tgt_hosts[roop_count], len); + tmp_tgt_hosts_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_usernames_lengths[roop_count])) + { + tmp_tgt_usernames[roop_count]= tmp_tgt_usernames_char; + memcpy(tmp_tgt_usernames_char, + share_alter->tmp_tgt_usernames[roop_count], len); + tmp_tgt_usernames_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_passwords_lengths[roop_count])) + { + tmp_tgt_passwords[roop_count]= tmp_tgt_passwords_char; + memcpy(tmp_tgt_passwords_char, + share_alter->tmp_tgt_passwords[roop_count], len); + tmp_tgt_passwords_char+= len + 1; + } + + if ((len= sizeof(char) * share_alter->tmp_tgt_sockets_lengths[roop_count])) + { + tmp_tgt_sockets[roop_count]= tmp_tgt_sockets_char; + memcpy(tmp_tgt_sockets_char, share_alter->tmp_tgt_sockets[roop_count], + len); + tmp_tgt_sockets_char+= len + 1; + } + + if ((len= + sizeof(char) * share_alter->tmp_tgt_wrappers_lengths[roop_count])) + { + tmp_tgt_wrappers[roop_count]= tmp_tgt_wrappers_char; + memcpy(tmp_tgt_wrappers_char, share_alter->tmp_tgt_wrappers[roop_count], + len); + tmp_tgt_wrappers_char+= len + 1; + } + + if ((len= sizeof(char) * share_alter->tmp_tgt_ssl_cas_lengths[roop_count])) + { + tmp_tgt_ssl_cas[roop_count]= tmp_tgt_ssl_cas_char; + memcpy(tmp_tgt_ssl_cas_char, share_alter->tmp_tgt_ssl_cas[roop_count], + len); + tmp_tgt_ssl_cas_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_ssl_capaths_lengths[roop_count])) + { + tmp_tgt_ssl_capaths[roop_count]= tmp_tgt_ssl_capaths_char; + memcpy(tmp_tgt_ssl_capaths_char, + share_alter->tmp_tgt_ssl_capaths[roop_count], len); + tmp_tgt_ssl_capaths_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_ssl_certs_lengths[roop_count])) + { + tmp_tgt_ssl_certs[roop_count]= tmp_tgt_ssl_certs_char; + memcpy(tmp_tgt_ssl_certs_char, + share_alter->tmp_tgt_ssl_certs[roop_count], len); + tmp_tgt_ssl_certs_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_ssl_ciphers_lengths[roop_count])) + { + tmp_tgt_ssl_ciphers[roop_count]= tmp_tgt_ssl_ciphers_char; + memcpy(tmp_tgt_ssl_ciphers_char, + share_alter->tmp_tgt_ssl_ciphers[roop_count], len); + tmp_tgt_ssl_ciphers_char+= len + 1; + } + + if ((len= sizeof(char) * share_alter->tmp_tgt_ssl_keys_lengths[roop_count])) + { + tmp_tgt_ssl_keys[roop_count]= tmp_tgt_ssl_keys_char; + memcpy(tmp_tgt_ssl_keys_char, share_alter->tmp_tgt_ssl_keys[roop_count], + len); + tmp_tgt_ssl_keys_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_default_files_lengths[roop_count])) + { + tmp_tgt_default_files[roop_count]= tmp_tgt_default_files_char; + memcpy(tmp_tgt_default_files_char, + share_alter->tmp_tgt_default_files[roop_count], len); + tmp_tgt_default_files_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_tgt_default_groups_lengths[roop_count])) + { + tmp_tgt_default_groups[roop_count]= tmp_tgt_default_groups_char; + memcpy(tmp_tgt_default_groups_char, + share_alter->tmp_tgt_default_groups[roop_count], len); + tmp_tgt_default_groups_char+= len + 1; + } + + if ((len= sizeof(char) * + share_alter->tmp_static_link_ids_lengths[roop_count])) { tmp_static_link_ids[roop_count] = tmp_static_link_ids_char; memcpy(tmp_static_link_ids_char, - share_alter->tmp_static_link_ids[roop_count], - sizeof(char) * share_alter->tmp_static_link_ids_lengths[roop_count]); - tmp_static_link_ids_char += - share_alter->tmp_static_link_ids_lengths[roop_count] + 1; + share_alter->tmp_static_link_ids[roop_count], len); + tmp_static_link_ids_char += len + 1; } } -- cgit v1.2.1 From 284810b3e89e56b35d92284786094e3df2febebe Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Thu, 19 Jan 2023 18:28:14 +1100 Subject: MDEV-30370 Fixing spider hang when server aborts This is Kentoku's patch for MDEV-22979 (e6e41f04f4e + 22a0097727f), which fixes 30370. It changes the wait to a timed wait for the first sts thread, which waits on server start to execute the init queries for spider. It also flips the flag init_command to false when the sts thread is being freed. With these changes the sts thread can check the flag regularly and abort the init_queries when it finds out the init_command is false. This avoids the deadlock that causes the problem in MDEV-30370. It also fixes MDEV-22979 for 10.4, but not 10.5. I have not tested higher versions for MDEV-22979. A test has also been done on MDEV-29904 to avoid regression, given MDEV-27233 is a similar problem and its patch caused the regression. The test passes for 10.4-11.0. However, this adhoc test only works consistently when placed in the main testsuite. We should not place spider tests in the main suite, so we do not include it in this commit. A patch for MDEV-27912 should fix this problem and allow a proper test for MDEV-29904. See comments in the jira ticket MDEV-30370/29904 for the adhoc testcase used for this commit. --- .../mysql-test/spider/bugfix/r/mdev_30370.result | 3 +++ .../mysql-test/spider/bugfix/t/mdev_30370.test | 5 +++++ storage/spider/spd_table.cc | 21 +++++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test (limited to 'storage/spider') diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result new file mode 100644 index 00000000000..df0f6949280 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result @@ -0,0 +1,3 @@ +# +# MDEV-30370 mariadbd hangs when running with --wsrep-recover and --plugin-load-add=ha_spider.so +# diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test new file mode 100644 index 00000000000..788ea2323f7 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test @@ -0,0 +1,5 @@ +--echo # +--echo # MDEV-30370 mariadbd hangs when running with --wsrep-recover and --plugin-load-add=ha_spider.so +--echo # + +--exec $MYSQLD_BOOTSTRAP_CMD --wsrep-recover --plugin-load-add=ha_spider.so diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index a6d2768703d..3dbc391b918 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -9877,6 +9877,7 @@ void spider_free_sts_threads( ) { bool thread_killed; DBUG_ENTER("spider_free_sts_threads"); + spider_thread->init_command = FALSE; pthread_mutex_lock(&spider_thread->mutex); thread_killed = spider_thread->killed; spider_thread->killed = TRUE; @@ -10033,20 +10034,32 @@ void *spider_table_bg_sts_action( tmp_disable_binlog(thd); thd->security_ctx->skip_grants(); thd->client_capabilities |= CLIENT_MULTI_RESULTS; - if (!(*spd_mysqld_server_started) && !thd->killed) + if (!(*spd_mysqld_server_started) && !thd->killed && !thread->killed) { pthread_mutex_lock(spd_LOCK_server_started); thd->mysys_var->current_cond = spd_COND_server_started; thd->mysys_var->current_mutex = spd_LOCK_server_started; - if (!(*spd_mysqld_server_started) && !thd->killed) + if (!(*spd_mysqld_server_started) && !thd->killed && !thread->killed && + thread->init_command) { - pthread_cond_wait(spd_COND_server_started, spd_LOCK_server_started); + do + { + struct timespec abstime; + set_timespec_nsec(abstime, 1000); + error_num = pthread_cond_timedwait(spd_COND_server_started, + spd_LOCK_server_started, &abstime); + } while ( + (error_num == ETIMEDOUT || error_num == ETIME) && + !(*spd_mysqld_server_started) && !thd->killed && !thread->killed && + thread->init_command + ); } pthread_mutex_unlock(spd_LOCK_server_started); thd->mysys_var->current_cond = &thread->cond; thd->mysys_var->current_mutex = &thread->mutex; } - while (spider_init_queries[i].length && !thd->killed) + while (spider_init_queries[i].length && !thd->killed && !thread->killed && + thread->init_command) { dispatch_command(COM_QUERY, thd, spider_init_queries[i].str, (uint) spider_init_queries[i].length, FALSE, FALSE); -- cgit v1.2.1