diff options
author | Yuchen Pei <yuchen.pei@mariadb.com> | 2023-05-03 12:06:59 +1000 |
---|---|---|
committer | Yuchen Pei <yuchen.pei@mariadb.com> | 2023-05-03 16:36:19 +1000 |
commit | 02212b6723a71200814ad81bdca576512077e842 (patch) | |
tree | b680abdd22b09c8da014e4f0b91dda77684d14f4 | |
parent | cb0e0c915f6de28f6f7f1a6dffdb697fc3b91417 (diff) | |
download | mariadb-git-bb-10.9-mdev-22979-27095-27233.tar.gz |
MDEV-22979 MDEV-27233 defer spider init from plugin-load-add to a temporary init filebb-10.9-mdev-22979-27095-27233
- Move spider init query execution from a background thread to
spider_db_init() so that it is fully synchronous, adapted from part
of the reverted commit c160a115b8b6dcd54bb3daf1a751ee9c68b7ee47
- if spider is initialised too early from init_server_components then
defer the init to a temporary init file
- also updated other init bug tests, for MDEV-29904 and MDEV-30370
22 files changed, 175 insertions, 87 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 32392ab882e..57835d7cf41 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -577,6 +577,7 @@ char mysql_real_data_home[FN_REFLEN], lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], *opt_init_file, *opt_tc_log_file, *opt_ddl_recovery_file; +char temp_init_file[FN_REFLEN] = ""; char *lc_messages_dir_ptr= lc_messages_dir, *log_error_file_ptr; char mysql_unpacked_real_data_home[FN_REFLEN]; size_t mysql_unpacked_real_data_home_len; @@ -5870,6 +5871,9 @@ int mysqld_main(int argc, char **argv) unireg_abort(1); } + if (*temp_init_file && !read_init_file(temp_init_file)) + my_delete(temp_init_file, MYF(0)); + if (opt_init_file && *opt_init_file) { if (read_init_file(opt_init_file)) diff --git a/sql/mysqld.h b/sql/mysqld.h index e649c83f3c9..c44d1fb1ed0 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -272,6 +272,7 @@ extern const char *myisam_recover_options_str; extern const LEX_CSTRING in_left_expr_name, in_additional_cond, in_having_cond; extern const LEX_CSTRING NULL_clex_str; extern const LEX_CSTRING error_clex_str; +extern char temp_init_file[]; extern SHOW_VAR status_vars[]; extern struct system_variables max_system_variables; extern struct system_status_var global_status_var; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 5a077a934ac..b8be9b5a676 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1583,6 +1583,40 @@ static void init_plugin_psi_keys(void) static void init_plugin_psi_keys(void) {} #endif /* HAVE_PSI_INTERFACE */ +/** Defers the initialisation of a dynamic plugin to a temporary init file */ +void plugin_defer_init(st_plugin_int &plugin) +{ + int fd; + const char *name= plugin.name.str; + const char *dl= plugin.plugin_dl->dl.str; + DBUG_ENTER("plugin_defer_init"); + if (!plugin.plugin_dl) + DBUG_VOID_RETURN; + if (!*temp_init_file) + { + if ((fd= create_temp_file(temp_init_file, mysql_tmpdir, + "plugin_init_", 0, MYF(MY_WME))) >= 0) + my_close(fd, MYF(0)); + else + { + sql_print_error("Loading of %s from %s failed as a temporary " + "file cannot be generated.", + name, dl); + DBUG_VOID_RETURN; + } + } + FILE *ofile= fopen(temp_init_file, "a"); + fprintf(ofile, "install plugin %s soname '%s';\n", name, dl); + fprintf(ofile, "delete from mysql.plugin where name=\"%s\" and dl=\"%s\";\n", + name, dl); + fclose(ofile); + sql_print_information("Loading of %s from %s is deferred to a temporary " + "init file", + name, dl); + plugin_del(&plugin, 0); + DBUG_VOID_RETURN; +} + /* The logic is that we first load and initialize all compiled in plugins. From there we load up the dynamic types (assuming we have not been told to @@ -1750,6 +1784,15 @@ int plugin_init(int *argc, char **argv, int flags) plugin_ptr= (struct st_plugin_int *) my_hash_element(hash, idx); if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED) { + if (plugin_ptr->plugin_dl && + (!strncmp(plugin_ptr->plugin_dl->dl.str, "ha_spider.so", + plugin_ptr->plugin_dl->dl.length) || + !strncmp(plugin_ptr->plugin_dl->dl.str, "ha_spider.dll", + plugin_ptr->plugin_dl->dl.length))) + { + plugin_defer_init(*plugin_ptr); + continue; + } bool plugin_table_engine= lex_string_eq(&plugin_table_engine_name, &plugin_ptr->name); bool opts_only= flags & PLUGIN_INIT_SKIP_INITIALIZATION && diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_22979.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_22979.result new file mode 100644 index 00000000000..affd26605fd --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_22979.result @@ -0,0 +1,3 @@ +MDEV-22979 "mysqld --bootstrap" / mysql_install_db hangs when Spider is installed +# Kill the server +# restart diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result new file mode 100644 index 00000000000..53622bb6a23 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result @@ -0,0 +1,3 @@ +# +# MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29904.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29904.result index c89309a514d..ae245a56b48 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_29904.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29904.result @@ -2,3 +2,4 @@ # MDEV-29904 SPIDER plugin initialization fails upon startup # # restart: --plugin-load-add=ha_spider +FOUND 3 /\[Note\] Loading of SPIDER[a-zA-Z0-9_]* from ha_spider(|.so|.dll) is deferred to a temporary init file/ in mysqld.1.1.err diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result index df0f6949280..25fc5ac9826 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30370.result @@ -1,3 +1,5 @@ # # MDEV-30370 mariadbd hangs when running with --wsrep-recover and --plugin-load-add=ha_spider.so # +# Kill the server +# restart diff --git a/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result new file mode 100644 index 00000000000..917b95f035a --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result @@ -0,0 +1,8 @@ +# +# plugin-load-add=ha_spider +# +FOUND 3 /\[Note\] Loading of SPIDER[a-zA-Z0-9_]* from ha_spider(|.so|.dll) is deferred to a temporary init file/ in mysqld.1.1.err +select * from mysql.plugin; +name dl +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_spider.result b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_spider.result new file mode 100644 index 00000000000..432d4282562 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_spider.result @@ -0,0 +1,8 @@ +# +# plugin-load-add=ha_spider +# +FOUND 1 /\[Note\] Loading of SPIDER[a-zA-Z0-9_]* from ha_spider(|.so|.dll) is deferred to a temporary init file/ in mysqld.1.1.err +select * from mysql.plugin; +name dl +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_22979.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_22979.test new file mode 100644 index 00000000000..441647e1edd --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_22979.test @@ -0,0 +1,16 @@ +--echo MDEV-22979 "mysqld --bootstrap" / mysql_install_db hangs when Spider is installed + +# This test is not the most faithful, as it does not have any +# dependency problems on the existence of the `mysql` database. To +# test MDEV-22979 faithfully, a mysql_install_db invocation with +# --plugin-load-add=ha_spider should be run. We cannot run it in mtr +# because we do not have access to --srcdir. + +let $MYSQLD_DATADIR= `select @@datadir`; +let $PLUGIN_DIR=`select @@plugin_dir`; +--source include/kill_mysqld.inc +--write_file $MYSQLTEST_VARDIR/tmp/mdev_22979.sql +drop table if exists foo.bar; +EOF +--exec $MYSQLD_CMD --datadir=$MYSQLD_DATADIR --bootstrap --plugin-dir=$PLUGIN_DIR --plugin-load-add=ha_spider < $MYSQLTEST_VARDIR/tmp/mdev_22979.sql +--source include/start_mysqld.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt new file mode 100644 index 00000000000..7bc1c2127a6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt @@ -0,0 +1 @@ +--init-file=$MYSQL_TEST_DIR/../storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql new file mode 100644 index 00000000000..2be9ec1fad6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql @@ -0,0 +1,3 @@ +INSTALL SONAME 'ha_spider.so'; +USE test; +CREATE TABLE t (c INT) ENGINE=SPIDER; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test new file mode 100644 index 00000000000..79603439d35 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test @@ -0,0 +1,3 @@ +--echo # +--echo # MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29904.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29904.test index d3dcb363890..eea172bc483 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_29904.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29904.test @@ -4,3 +4,7 @@ --let $restart_parameters=--plugin-load-add=ha_spider --source include/restart_mysqld.inc +--let SEARCH_PATTERN=\\[Note\\] Loading of SPIDER[a-zA-Z0-9_]* from ha_spider(|.so|.dll) is deferred to a temporary init file +--let SEARCH_FILE=`select regexp_replace(@@tmpdir, '^.*/','')` +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/$SEARCH_FILE.err +--source include/search_pattern_in_file.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test index 788ea2323f7..d4d5296af55 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30370.test @@ -2,4 +2,8 @@ --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 +let $MYSQLD_DATADIR= `select @@datadir`; +let $PLUGIN_DIR=`select @@plugin_dir`; +--source include/kill_mysqld.inc +--exec $MYSQLD_CMD --datadir=$MYSQLD_DATADIR --wsrep-recover --plugin-dir=$PLUGIN_DIR --plugin-load-add=ha_spider +--source include/start_mysqld.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.opt b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.opt new file mode 100644 index 00000000000..924ea4e31ef --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.opt @@ -0,0 +1 @@ +--plugin-load-add=ha_spider diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test new file mode 100644 index 00000000000..bc32a6b3147 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test @@ -0,0 +1,11 @@ +--echo # +--echo # plugin-load-add=ha_spider +--echo # + +--let SEARCH_PATTERN=\\[Note\\] Loading of SPIDER[a-zA-Z0-9_]* from ha_spider(|.so|.dll) is deferred to a temporary init file +--let SEARCH_FILE=`select regexp_replace(@@tmpdir, '^.*/','')` +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/$SEARCH_FILE.err +--source include/search_pattern_in_file.inc +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.opt b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.opt new file mode 100644 index 00000000000..bf4180ca67a --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.opt @@ -0,0 +1 @@ +--plugin-load-add=SPIDER=ha_spider diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.test b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.test new file mode 100644 index 00000000000..bc32a6b3147 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_spider.test @@ -0,0 +1,11 @@ +--echo # +--echo # plugin-load-add=ha_spider +--echo # + +--let SEARCH_PATTERN=\\[Note\\] Loading of SPIDER[a-zA-Z0-9_]* from ha_spider(|.so|.dll) is deferred to a temporary init file +--let SEARCH_FILE=`select regexp_replace(@@tmpdir, '^.*/','')` +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/$SEARCH_FILE.err +--source include/search_pattern_in_file.inc +select * from mysql.plugin; +create table t (c int) Engine=SPIDER; +drop table t; diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 917b3bfe6ec..6fa661330c5 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -199,7 +199,6 @@ typedef struct st_spider_thread volatile bool killed; volatile bool thd_wait; volatile bool first_free_wait; - volatile bool init_command; volatile int error; pthread_t thread; pthread_cond_t cond; diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index 76435b81dd9..d1b6b6ddbfa 100644 --- a/storage/spider/spd_init_query.h +++ b/storage/spider/spd_init_query.h @@ -698,6 +698,5 @@ static LEX_STRING spider_init_queries[] = { " create function if not exists spider_flush_table_mon_cache returns int" " soname 'ha_spider.dll';" "end if;" - )}, - {C_STRING_WITH_LEN("")} + )} }; diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 2c39ad359f2..d064a7c7f5c 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -125,9 +125,6 @@ const char **spd_mysqld_unix_port; uint *spd_mysqld_port; bool volatile *spd_abort_loop; Time_zone *spd_tz_system; -static int *spd_mysqld_server_started; -static pthread_mutex_t *spd_LOCK_server_started; -static pthread_cond_t *spd_COND_server_started; extern long spider_conn_mutex_id; handlerton *spider_hton_ptr; SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; @@ -6286,28 +6283,6 @@ handler* spider_create_handler( MEM_ROOT *mem_root ) { DBUG_ENTER("spider_create_handler"); - SPIDER_THREAD *thread = &spider_table_sts_threads[0]; - if (unlikely(thread->init_command)) - { - THD *thd = current_thd; - pthread_cond_t *cond = thd->mysys_var->current_cond; - pthread_mutex_t *mutex = thd->mysys_var->current_mutex; - /* wait for finishing init_command */ - pthread_mutex_lock(&thread->mutex); - if (unlikely(thread->init_command)) - { - thd->mysys_var->current_cond = &thread->sync_cond; - thd->mysys_var->current_mutex = &thread->mutex; - pthread_cond_wait(&thread->sync_cond, &thread->mutex); - } - pthread_mutex_unlock(&thread->mutex); - thd->mysys_var->current_cond = cond; - thd->mysys_var->current_mutex = mutex; - if (thd->killed) - { - DBUG_RETURN(NULL); - } - } DBUG_RETURN(new (mem_root) ha_spider(hton, table)); } @@ -6561,6 +6536,45 @@ int spider_panic( DBUG_RETURN(0); } +/** + Run spider init queries + + @retval false success + @retval true failure +*/ +bool spider_run_init_queries() +{ + DBUG_ENTER("spider_init_system_tables"); + + MYSQL *mysql= mysql_init(NULL); + if (!mysql) + DBUG_RETURN(TRUE); + if (!mysql_real_connect_local(mysql)) + { + mysql_close(mysql); + DBUG_RETURN(TRUE); + } + + int size= sizeof(spider_init_queries) / sizeof(spider_init_queries[0]); + for (int i= 0; i < size; i++) + { + if (mysql_real_query(mysql, spider_init_queries[i].str, + spider_init_queries[i].length)) + { + fprintf(stderr, + "[ERROR] SPIDER plugin initialization failed at '%s' by '%s'\n", + spider_init_queries[i].str, mysql_error(mysql)); + + mysql_close(mysql); + DBUG_RETURN(TRUE); + } + if (MYSQL_RES *res= mysql_store_result(mysql)) + mysql_free_result(res); + } + mysql_close(mysql); + DBUG_RETURN(FALSE); +} + int spider_db_init( void *p ) { @@ -6645,9 +6659,6 @@ int spider_db_init( spd_mysqld_port = &mysqld_port; spd_abort_loop = &abort_loop; spd_tz_system = my_tz_SYSTEM; - spd_mysqld_server_started = &mysqld_server_started; - spd_LOCK_server_started = &LOCK_server_started; - spd_COND_server_started = &COND_server_started; #ifdef HAVE_PSI_INTERFACE init_spider_psi_keys(); @@ -6825,6 +6836,11 @@ int spider_db_init( spider_udf_table_mon_list_hash[roop_count].array.size_of_element); } + if (spider_run_init_queries()) + { + goto error_system_table_creation; + } + if (!(spider_table_sts_threads = (SPIDER_THREAD *) spider_bulk_malloc(NULL, 256, MYF(MY_WME | MY_ZEROFILL), &spider_table_sts_threads, (uint) (sizeof(SPIDER_THREAD) * @@ -6834,7 +6850,6 @@ int spider_db_init( NullS)) ) goto error_alloc_mon_mutxes; - spider_table_sts_threads[0].init_command = TRUE; for (roop_count = 0; roop_count < (int) spider_param_table_sts_thread_count(); @@ -6910,6 +6925,7 @@ error_init_udf_table_mon_list_hash: error_init_udf_table_mon_cond: for (; roop_count >= 0; roop_count--) pthread_cond_destroy(&spider_udf_table_mon_conds[roop_count]); +error_system_table_creation: roop_count = spider_param_udf_table_mon_mutex_count() - 1; error_init_udf_table_mon_mutex: for (; roop_count >= 0; roop_count--) @@ -9001,7 +9017,6 @@ 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; @@ -9133,59 +9148,6 @@ void *spider_table_bg_sts_action( trx->thd = thd; /* init end */ - if (thread->init_command) - { - uint i = 0; - tmp_disable_binlog(thd); - thd->security_ctx->skip_grants(); - thd->client_capabilities |= CLIENT_MULTI_RESULTS; - 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 && !thread->killed && - thread->init_command) - { - 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; - } - bool spd_wsrep_on = thd->variables.wsrep_on; - thd->variables.wsrep_on = false; - 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); - if (unlikely(thd->is_error())) - { - fprintf(stderr, "[ERROR] %s\n", spider_stmt_da_message(thd)); - thd->clear_error(); - break; - } - ++i; - } - thd->variables.wsrep_on = spd_wsrep_on; - thd->mysys_var->current_cond = &thread->cond; - thd->mysys_var->current_mutex = &thread->mutex; - thd->client_capabilities -= CLIENT_MULTI_RESULTS; - reenable_binlog(thd); - thread->init_command = FALSE; - pthread_cond_broadcast(&thread->sync_cond); - } if (thd->killed) { thread->killed = TRUE; |