Commit db50919f authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent f3f09def
...@@ -521,3 +521,10 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'show status like \'server_audit_ ...@@ -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,QUERY,sa_db,'show variables like \'server_audit%\'',0
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,plugin, TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,plugin,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'uninstall plugin server_audit',0 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
...@@ -235,3 +235,8 @@ uninstall plugin server_audit; ...@@ -235,3 +235,8 @@ uninstall plugin server_audit;
cat_file $MYSQLD_DATADIR/server_audit.log; cat_file $MYSQLD_DATADIR/server_audit.log;
remove_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;
...@@ -323,7 +323,7 @@ static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *, ...@@ -323,7 +323,7 @@ static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
struct st_plugin_int **); struct st_plugin_int **);
static void unlock_variables(THD *thd, struct system_variables *vars); static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(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 restore_ptr_backup(uint n, st_ptr_backup *backup);
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
static void reap_plugins(void); static void reap_plugins(void);
...@@ -1269,7 +1269,7 @@ static void plugin_del(struct st_plugin_int *plugin) ...@@ -1269,7 +1269,7 @@ static void plugin_del(struct st_plugin_int *plugin)
DBUG_ENTER("plugin_del"); DBUG_ENTER("plugin_del");
mysql_mutex_assert_owner(&LOCK_plugin); mysql_mutex_assert_owner(&LOCK_plugin);
/* Free allocated strings before deleting the 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); restore_ptr_backup(plugin->nbackups, plugin->ptr_backup);
if (plugin->plugin_dl) if (plugin->plugin_dl)
{ {
...@@ -2909,6 +2909,7 @@ sys_var *find_sys_var(THD *thd, const char *str, size_t length, ...@@ -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. called by register_var, construct_options and test_plugin_options.
Returns the 'bookmark' for the named variable. Returns the 'bookmark' for the named variable.
returns null for non thd-local variables.
LOCK_system_variables_hash should be at least read locked LOCK_system_variables_hash should be at least read locked
*/ */
static st_bookmark *find_bookmark(const char *plugin, const char *name, static st_bookmark *find_bookmark(const char *plugin, const char *name,
...@@ -2965,7 +2966,6 @@ static size_t var_storage_size(int flags) ...@@ -2965,7 +2966,6 @@ static size_t var_storage_size(int flags)
/* /*
returns a bookmark for thd-local variables, creating if neccessary. 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 Requires that a write lock is obtained on LOCK_system_variables_hash
*/ */
static st_bookmark *register_var(const char *plugin, const char *name, static st_bookmark *register_var(const char *plugin, const char *name,
...@@ -3316,27 +3316,35 @@ void plugin_thdvar_cleanup(THD *thd) ...@@ -3316,27 +3316,35 @@ void plugin_thdvar_cleanup(THD *thd)
variables are no longer accessible and the value space is lost. Note variables are no longer accessible and the value space is lost. Note
that only string values with PLUGIN_VAR_MEMALLOC are allocated and that only string values with PLUGIN_VAR_MEMALLOC are allocated and
must be freed. 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"); 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 ((var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
if (piv && var->flags & PLUGIN_VAR_MEMALLOC)
((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
(piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
{ {
/* Free the string from global_system_variables. */ char **val;
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL); 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", DBUG_PRINT("plugin", ("freeing value for: '%s' addr: %p",
var->name.str, valptr)); var->name, val));
my_free(*valptr); my_free(*val);
*valptr= NULL; *val= NULL;
} }
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -3996,7 +4004,7 @@ static my_option *construct_help_options(MEM_ROOT *mem_root, ...@@ -3996,7 +4004,7 @@ static my_option *construct_help_options(MEM_ROOT *mem_root,
bzero(opts, sizeof(my_option) * count); 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 have their names prefixed with the plugin name. Restore the names here
to get the correct (not double-prefixed) help text. to get the correct (not double-prefixed) help text.
We won't need @@sysvars anymore and don't care about their proper names. 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, ...@@ -4100,9 +4108,6 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
char *varname; char *varname;
sys_var *v; sys_var *v;
if (o->flags & PLUGIN_VAR_NOSYSVAR)
continue;
tmp_backup[tmp->nbackups++].save(&o->name); tmp_backup[tmp->nbackups++].save(&o->name);
if ((var= find_bookmark(tmp->name.str, o->name, o->flags))) 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, ...@@ -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); my_casedn_str(&my_charset_latin1, varname);
convert_dash_to_underscore(varname, len-1); 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; const char *s= o->flags & PLUGIN_VAR_DEPRECATED ? "" : NULL;
v= new (mem_root) sys_var_pluginvar(&chain, varname, tmp, o, s); v= new (mem_root) sys_var_pluginvar(&chain, varname, tmp, o, s);
v->test_load= (var ? &var->loaded : &static_unload); v->test_load= (var ? &var->loaded : &static_unload);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment