diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index f59354625b345..a2dee95d78fe2 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -166,6 +166,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/opt_hints.cc ../sql/opt_hints.h ../sql/opt_trace_ddl_info.cc ../sql/opt_trace_ddl_info.h ../sql/sql_path.cc + ../sql/removed_option_registry.cc + ../sql/removed_option_sql.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) diff --git a/mysql-test/suite/sys_vars/r/removed_options.result b/mysql-test/suite/sys_vars/r/removed_options.result new file mode 100644 index 0000000000000..3b8af04d2f897 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/removed_options.result @@ -0,0 +1,11 @@ +# +# MDEV-39252 At runtime list removed variables that have been set +# +# +# List INFORMATION_SCHEMA.REMOVED_STARTUP_OPTIONS +# Use --nowarnings +# +SELECT OPTION_NAME, OPTION_VALUE, SOURCE, HANDLING FROM INFORMATION_SCHEMA.REMOVED_STARTUP_OPTIONS; +OPTION_NAME OPTION_VALUE SOURCE HANDLING +innodb-log-files-in-group 2 CONFIG IGNORED +innodb-thread-concurrency 8 COMMAND_LINE IGNORED diff --git a/mysql-test/suite/sys_vars/t/removed_options.cnf b/mysql-test/suite/sys_vars/t/removed_options.cnf new file mode 100644 index 0000000000000..bb48cb922d95b --- /dev/null +++ b/mysql-test/suite/sys_vars/t/removed_options.cnf @@ -0,0 +1,4 @@ +!include include/default_my.cnf + +[mysqld.1] +innodb_log_files_in_group=2 diff --git a/mysql-test/suite/sys_vars/t/removed_options.opt b/mysql-test/suite/sys_vars/t/removed_options.opt new file mode 100644 index 0000000000000..c0bf855aa76b2 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/removed_options.opt @@ -0,0 +1 @@ +--innodb-thread-concurrency=8 \ No newline at end of file diff --git a/mysql-test/suite/sys_vars/t/removed_options.test b/mysql-test/suite/sys_vars/t/removed_options.test new file mode 100644 index 0000000000000..dd4d2353b7b2d --- /dev/null +++ b/mysql-test/suite/sys_vars/t/removed_options.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-39252 At runtime list removed variables that have been set +--echo # + +--echo # +--echo # List INFORMATION_SCHEMA.REMOVED_STARTUP_OPTIONS +--echo # Use --nowarnings +--echo # +SELECT OPTION_NAME, OPTION_VALUE, SOURCE, HANDLING FROM INFORMATION_SCHEMA.REMOVED_STARTUP_OPTIONS; diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index e54e894e1d0fc..8bd265aa05088 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -158,6 +158,8 @@ SET (SQL_SOURCE sql_signal.cc mdl.cc sql_admin.cc transaction.cc sys_vars.cc sql_truncate.cc datadict.cc sql_reload.cc + removed_option_registry.cc + removed_option_sql.cc # added in MariaDB: grant.cc diff --git a/sql/handler.h b/sql/handler.h index 354e5d6192d6a..0ac143d494819 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1098,6 +1098,7 @@ enum enum_schema_tables SCH_PROCESSLIST, SCH_PROFILES, SCH_REFERENTIAL_CONSTRAINTS, + SCH_REMOVED_STARTUP_OPTIONS, SCH_PROCEDURES, SCH_SCHEMATA, SCH_SCHEMA_PRIVILEGES, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5ffff2cb12851..22b7173aeffca 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -136,6 +136,8 @@ #include +#include "removed_option_registry.h" + #define mysqld_charset &my_charset_latin1 extern "C" { // Because of SCO 3.2V4.2 @@ -1985,6 +1987,8 @@ static void clean_up(bool print_message) if (cleanup_done++) return; /* purecov: inspected */ + free_removed_startup_option_registry(); + #ifdef HAVE_REPLICATION // We must call end_slave() as clean_up may have been called during startup end_slave(); @@ -5000,6 +5004,9 @@ static int init_server_components() DBUG_ENTER("init_server_components"); bool binlog_engine_used= false; + if (init_removed_startup_option_registry()) + unireg_abort(1); + /* We need to call each of these following functions to ensure that all things are initialized so that unireg_abort() doesn't fail @@ -8470,6 +8477,8 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, #endif break; case OPT_REMOVED_OPTION: + if (register_removed_startup_option(opt->name, argument, filename)) + sql_print_warning("Failed to record removed option '%s'", opt->name); sql_print_warning("'%s' was removed. It does nothing now and exists only " "for compatibility with old my.cnf files.", opt->name); /* Restore default value (to show that the option cannot be used) */ diff --git a/sql/removed_option_registry.cc b/sql/removed_option_registry.cc new file mode 100644 index 0000000000000..65ab05ba86398 --- /dev/null +++ b/sql/removed_option_registry.cc @@ -0,0 +1,75 @@ +#include "removed_option_registry.h" + +#include +#include +#include + +static std::vector g_removed_startup_options; +static std::mutex g_removed_startup_options_lock; + +bool init_removed_startup_option_registry() +{ + return false; +} + +void free_removed_startup_option_registry() +{ + std::lock_guard guard(g_removed_startup_options_lock); + g_removed_startup_options.clear(); + g_removed_startup_options.shrink_to_fit(); +} + +bool register_removed_startup_option(const char *name, + const char *value, + const char *filename) +{ + Removed_startup_option row; + + row.option_name= name ? name : ""; + row.option_value= value ? value : ""; + + if (filename && *filename) + { + row.source= "CONFIG"; + row.config_file= filename; + } + else + { + row.source= "COMMAND_LINE"; + row.config_file.clear(); + } + + row.handling= "IGNORED"; + + try + { + std::lock_guard guard(g_removed_startup_options_lock); + g_removed_startup_options.push_back(row); + } + catch (const std::bad_alloc &) + { + return true; + } + + return false; +} + +size_t removed_startup_option_count() +{ + std::lock_guard guard(g_removed_startup_options_lock); + return g_removed_startup_options.size(); +} + +bool get_removed_startup_option_copy(size_t index, Removed_startup_option *out) +{ + if (!out) + return true; + + std::lock_guard guard(g_removed_startup_options_lock); + + if (index >= g_removed_startup_options.size()) + return true; + + *out= g_removed_startup_options[index]; + return false; +} diff --git a/sql/removed_option_registry.h b/sql/removed_option_registry.h new file mode 100644 index 0000000000000..86b888f0688c8 --- /dev/null +++ b/sql/removed_option_registry.h @@ -0,0 +1,26 @@ +#ifndef REMOVED_OPTION_REGISTRY_H +#define REMOVED_OPTION_REGISTRY_H + +#include +#include + +struct Removed_startup_option +{ + std::string option_name; + std::string option_value; + std::string source; // "CONFIG" or "COMMAND_LINE" + std::string config_file; // empty if not from config file + std::string handling; // "IGNORED" +}; + +bool init_removed_startup_option_registry(); +void free_removed_startup_option_registry(); + +bool register_removed_startup_option(const char *name, + const char *value, + const char *filename); + +size_t removed_startup_option_count(); +bool get_removed_startup_option_copy(size_t index, Removed_startup_option *out); + +#endif diff --git a/sql/removed_option_sql.cc b/sql/removed_option_sql.cc new file mode 100644 index 0000000000000..a705232578812 --- /dev/null +++ b/sql/removed_option_sql.cc @@ -0,0 +1,87 @@ +#include "my_global.h" +#include "sql_i_s.h" +#include "sql_class.h" +#include "table.h" +#include "field.h" +#include "sql_acl.h" +#include "removed_option_registry.h" + +using namespace Show; + +enum enum_removed_startup_options_fields +{ + RSO_OPTION_NAME = 0, + RSO_OPTION_VALUE, + RSO_SOURCE, + RSO_CONFIG_FILE, + RSO_HANDLING +}; + +ST_FIELD_INFO removed_startup_options_fields_info[] = +{ + Column("OPTION_NAME", Varchar(128), NOT_NULL, "Option_name"), + Column("OPTION_VALUE", Varchar(1024), NULLABLE, "Option_value"), + Column("SOURCE", Varchar(32), NOT_NULL, "Source"), + Column("CONFIG_FILE", Varchar(1024), NULLABLE, "Config_file"), + Column("HANDLING", Varchar(32), NOT_NULL, "Handling"), + CEnd() +}; + +int fill_schema_removed_startup_options(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *table = tables->table; + size_t i, cnt; + (void) cond; + + if (check_global_access(thd, PROCESS_ACL, true)) + return 0; + + cnt = removed_startup_option_count(); + + for (i = 0; i < cnt; ++i) + { + Removed_startup_option row; + + if (get_removed_startup_option_copy(i, &row)) + continue; + + restore_record(table, s->default_values); + + table->field[RSO_OPTION_NAME]->store(row.option_name.c_str(), + (uint32) row.option_name.length(), + system_charset_info); + + if (!row.option_value.empty()) + { + table->field[RSO_OPTION_VALUE]->store(row.option_value.c_str(), + (uint32) row.option_value.length(), + system_charset_info); + table->field[RSO_OPTION_VALUE]->set_notnull(); + } + else + table->field[RSO_OPTION_VALUE]->set_null(); + + table->field[RSO_SOURCE]->store(row.source.c_str(), + (uint32) row.source.length(), + system_charset_info); + + if (!row.config_file.empty()) + { + table->field[RSO_CONFIG_FILE]->store(row.config_file.c_str(), + (uint32) row.config_file.length(), + system_charset_info); + table->field[RSO_CONFIG_FILE]->set_notnull(); + } + else + table->field[RSO_CONFIG_FILE]->set_null(); + + table->field[RSO_HANDLING]->store(row.handling.c_str(), + (uint32) row.handling.length(), + system_charset_info); + + if (schema_table_store_record(thd, table)) + return 1; + } + + return 0; +} diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2b4aa9ce702c7..81ef65defcb1b 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -191,6 +191,8 @@ static bool trylock_short(mysql_mutex_t *mutex) return 1; } +extern ST_FIELD_INFO removed_startup_options_fields_info[]; +int fill_schema_removed_startup_options(THD *thd, TABLE_LIST *tables, COND *cond); /*************************************************************************** ** List all table types supported @@ -11017,6 +11019,9 @@ ST_SCHEMA_TABLE schema_tables[]= Show::referential_constraints_fields_info, 0, get_all_tables, 0, get_referential_constraints_record, 1, 9, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, + {"REMOVED_STARTUP_OPTIONS"_Lex_ident_i_s_table, + removed_startup_options_fields_info, 0, + fill_schema_removed_startup_options, 0, 0, -1, -1, 0, 0}, {"ROUTINES"_Lex_ident_i_s_table, Show::proc_fields_info, 0, fill_schema_proc, make_proc_old_format, 0, 2, 3, 0, 0}, {"SCHEMATA"_Lex_ident_i_s_table, Show::schema_fields_info, 0,