Commit 8549a8ea authored by thek@adventure.(none)'s avatar thek@adventure.(none)

Bug#31347 Increase in memory usage after many DROP USER statements

Dropping users causes huge increase in memory usage because field values were
allocated on the server memory root for temporary usage but never deallocated.

This patch changes the target memory root to be that of the thread handler
instead since this root is cleared between each statement.
parent b2264ff8
...@@ -311,7 +311,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -311,7 +311,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
continue; continue;
} }
const char *password= get_field(&mem, table->field[2]); const char *password= get_field(thd->mem_root, table->field[2]);
uint password_len= password ? strlen(password) : 0; uint password_len= password ? strlen(password) : 0;
set_user_salt(&user, password, password_len); set_user_salt(&user, password, password_len);
if (user.salt_len == 0 && password_len != 0) if (user.salt_len == 0 && password_len != 0)
...@@ -364,7 +364,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -364,7 +364,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
/* Starting from 4.0.2 we have more fields */ /* Starting from 4.0.2 we have more fields */
if (table->s->fields >= 31) if (table->s->fields >= 31)
{ {
char *ssl_type=get_field(&mem, table->field[next_field++]); char *ssl_type=get_field(thd->mem_root, table->field[next_field++]);
if (!ssl_type) if (!ssl_type)
user.ssl_type=SSL_TYPE_NONE; user.ssl_type=SSL_TYPE_NONE;
else if (!strcmp(ssl_type, "ANY")) else if (!strcmp(ssl_type, "ANY"))
...@@ -378,11 +378,11 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -378,11 +378,11 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
user.x509_issuer= get_field(&mem, table->field[next_field++]); user.x509_issuer= get_field(&mem, table->field[next_field++]);
user.x509_subject= get_field(&mem, table->field[next_field++]); user.x509_subject= get_field(&mem, table->field[next_field++]);
char *ptr = get_field(&mem, table->field[next_field++]); char *ptr = get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.questions=ptr ? atoi(ptr) : 0; user.user_resource.questions=ptr ? atoi(ptr) : 0;
ptr = get_field(&mem, table->field[next_field++]); ptr = get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.updates=ptr ? atoi(ptr) : 0; user.user_resource.updates=ptr ? atoi(ptr) : 0;
ptr = get_field(&mem, table->field[next_field++]); ptr = get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0; user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0;
if (user.user_resource.questions || user.user_resource.updates || if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.conn_per_hour) user.user_resource.conn_per_hour)
...@@ -391,7 +391,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -391,7 +391,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
if (table->s->fields >= 36) if (table->s->fields >= 36)
{ {
/* Starting from 5.0.3 we have max_user_connections field */ /* Starting from 5.0.3 we have max_user_connections field */
ptr= get_field(&mem, table->field[next_field++]); ptr= get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.user_conn= ptr ? atoi(ptr) : 0; user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
} }
else else
...@@ -4865,6 +4865,7 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop, ...@@ -4865,6 +4865,7 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
byte user_key[MAX_KEY_LENGTH]; byte user_key[MAX_KEY_LENGTH];
uint key_prefix_length; uint key_prefix_length;
DBUG_ENTER("handle_grant_table"); DBUG_ENTER("handle_grant_table");
THD *thd= current_thd;
if (! table_no) // mysql.user table if (! table_no) // mysql.user table
{ {
...@@ -4932,17 +4933,18 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop, ...@@ -4932,17 +4933,18 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
DBUG_PRINT("info",("scan error: %d", error)); DBUG_PRINT("info",("scan error: %d", error));
continue; continue;
} }
if (! (host= get_field(&mem, host_field))) if (! (host= get_field(thd->mem_root, host_field)))
host= ""; host= "";
if (! (user= get_field(&mem, user_field))) if (! (user= get_field(thd->mem_root, user_field)))
user= ""; user= "";
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan fields: '%s'@'%s' '%s' '%s' '%s'", DBUG_PRINT("loop",("scan fields: '%s'@'%s' '%s' '%s' '%s'",
user, host, user, host,
get_field(&mem, table->field[1]) /*db*/, get_field(thd->mem_root, table->field[1]) /*db*/,
get_field(&mem, table->field[3]) /*table*/, get_field(thd->mem_root, table->field[3]) /*table*/,
get_field(&mem, table->field[4]) /*column*/)); get_field(thd->mem_root,
table->field[4]) /*column*/));
#endif #endif
if (strcmp(user_str, user) || if (strcmp(user_str, user) ||
my_strcasecmp(system_charset_info, host_str, host)) my_strcasecmp(system_charset_info, host_str, host))
......
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