diff options
author | Sergei Golubchik <serg@mariadb.org> | 2023-01-19 21:53:16 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2023-01-20 15:44:15 +0100 |
commit | db50919f97c96a5c2369b87c856781089fcd9c18 (patch) | |
tree | ce3f97736908c97eff0098bed1537e28d246e379 | |
parent | f3f09def230698509eb4b7cbbe9d7cb00088cdef (diff) | |
download | mariadb-git-db50919f97c96a5c2369b87c856781089fcd9c18.tar.gz |
MDEV-27631 Assertion `global_status_var.global_memory_used == 0' failed in mysqld_exit
plugin_vars_free_values() was walking plugin sysvars and thus
did not free memory of plugin PLUGIN_VAR_NOSYSVAR vars.
* change it to walk all plugin vars
* add the pluginname_ prefix to NOSYSVARS var names too,
so that plugin_vars_free_values() would be able to find their
bookmarks
-rw-r--r-- | mysql-test/suite/plugins/r/server_audit.result | 7 | ||||
-rw-r--r-- | mysql-test/suite/plugins/t/server_audit.test | 5 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 51 |
3 files changed, 43 insertions, 20 deletions
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 9768040aa94..fc9d98f5d0a 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -521,3 +521,10 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'show status like \'server_audit_ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'show variables like \'server_audit%\'',0 TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,plugin, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'uninstall plugin server_audit',0 +# +# MDEV-27631 Assertion `global_status_var.global_memory_used == 0' failed in mysqld_exit +# +install plugin server_audit soname 'server_audit'; +uninstall plugin server_audit; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index d8f8b9d0165..5048ccc2446 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -235,3 +235,8 @@ uninstall plugin server_audit; cat_file $MYSQLD_DATADIR/server_audit.log; remove_file $MYSQLD_DATADIR/server_audit.log; +--echo # +--echo # MDEV-27631 Assertion `global_status_var.global_memory_used == 0' failed in mysqld_exit +--echo # +install plugin server_audit soname 'server_audit'; +uninstall plugin server_audit; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 4ab329c454a..1a4d6cba7d3 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -323,7 +323,7 @@ static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *, struct st_plugin_int **); static void unlock_variables(THD *thd, struct system_variables *vars); static void cleanup_variables(struct system_variables *vars); -static void plugin_vars_free_values(sys_var *vars); +static void plugin_vars_free_values(st_mysql_sys_var **vars); static void restore_ptr_backup(uint n, st_ptr_backup *backup); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); @@ -1269,7 +1269,7 @@ static void plugin_del(struct st_plugin_int *plugin) DBUG_ENTER("plugin_del"); mysql_mutex_assert_owner(&LOCK_plugin); /* Free allocated strings before deleting the plugin. */ - plugin_vars_free_values(plugin->system_vars); + plugin_vars_free_values(plugin->plugin->system_vars); restore_ptr_backup(plugin->nbackups, plugin->ptr_backup); if (plugin->plugin_dl) { @@ -2909,6 +2909,7 @@ sys_var *find_sys_var(THD *thd, const char *str, size_t length, /* called by register_var, construct_options and test_plugin_options. Returns the 'bookmark' for the named variable. + returns null for non thd-local variables. LOCK_system_variables_hash should be at least read locked */ static st_bookmark *find_bookmark(const char *plugin, const char *name, @@ -2965,7 +2966,6 @@ static size_t var_storage_size(int flags) /* returns a bookmark for thd-local variables, creating if neccessary. - returns null for non thd-local variables. Requires that a write lock is obtained on LOCK_system_variables_hash */ static st_bookmark *register_var(const char *plugin, const char *name, @@ -3316,27 +3316,35 @@ void plugin_thdvar_cleanup(THD *thd) variables are no longer accessible and the value space is lost. Note that only string values with PLUGIN_VAR_MEMALLOC are allocated and must be freed. - - @param[in] vars Chain of system variables of a plugin */ -static void plugin_vars_free_values(sys_var *vars) +static void plugin_vars_free_values(st_mysql_sys_var **vars) { DBUG_ENTER("plugin_vars_free_values"); - for (sys_var *var= vars; var; var= var->next) + if (!vars) + DBUG_VOID_RETURN; + + while(st_mysql_sys_var *var= *vars++) { - sys_var_pluginvar *piv= var->cast_pluginvar(); - if (piv && - ((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) && - (piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC)) + if ((var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR && + var->flags & PLUGIN_VAR_MEMALLOC) { - /* Free the string from global_system_variables. */ - char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL); + char **val; + if (var->flags & PLUGIN_VAR_THDLOCAL) + { + st_bookmark *v= find_bookmark(0, var->name, var->flags); + if (!v) + continue; + val= (char**)(global_system_variables.dynamic_variables_ptr + v->offset); + } + else + val= *(char***) (var + 1); + DBUG_PRINT("plugin", ("freeing value for: '%s' addr: %p", - var->name.str, valptr)); - my_free(*valptr); - *valptr= NULL; + var->name, val)); + my_free(*val); + *val= NULL; } } DBUG_VOID_RETURN; @@ -3996,7 +4004,7 @@ static my_option *construct_help_options(MEM_ROOT *mem_root, bzero(opts, sizeof(my_option) * count); /** - some plugin variables (those that don't have PLUGIN_VAR_NOSYSVAR flag) + some plugin variables have their names prefixed with the plugin name. Restore the names here to get the correct (not double-prefixed) help text. We won't need @@sysvars anymore and don't care about their proper names. @@ -4100,9 +4108,6 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, char *varname; sys_var *v; - if (o->flags & PLUGIN_VAR_NOSYSVAR) - continue; - tmp_backup[tmp->nbackups++].save(&o->name); if ((var= find_bookmark(tmp->name.str, o->name, o->flags))) { @@ -4118,6 +4123,12 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, my_casedn_str(&my_charset_latin1, varname); convert_dash_to_underscore(varname, len-1); } + if (o->flags & PLUGIN_VAR_NOSYSVAR) + { + o->name= varname; + continue; + } + const char *s= o->flags & PLUGIN_VAR_DEPRECATED ? "" : NULL; v= new (mem_root) sys_var_pluginvar(&chain, varname, tmp, o, s); v->test_load= (var ? &var->loaded : &static_unload); |