Skip to content

Commit b4ff645

Browse files
committed
Fixed wrong counting of global Memory_used
1 parent 7c6cb41 commit b4ff645

File tree

12 files changed

+111
-51
lines changed

12 files changed

+111
-51
lines changed

include/mysql/plugin.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ struct st_mysql_show_var {
194194
enum enum_mysql_show_type type;
195195
};
196196

197+
struct system_status_var;
198+
197199
#define SHOW_VAR_FUNC_BUFF_SIZE (256 * sizeof(void*))
198-
typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, enum enum_var_type);
200+
typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
199201

200202

201203
/*

include/mysql/plugin_audit.h.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@
281281
void *value;
282282
enum enum_mysql_show_type type;
283283
};
284-
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
284+
struct system_status_var;
285+
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
285286
struct st_mysql_sys_var;
286287
struct st_mysql_value;
287288
typedef int (*mysql_var_check_func)(void* thd,

include/mysql/plugin_auth.h.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@
281281
void *value;
282282
enum enum_mysql_show_type type;
283283
};
284-
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
284+
struct system_status_var;
285+
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
285286
struct st_mysql_sys_var;
286287
struct st_mysql_value;
287288
typedef int (*mysql_var_check_func)(void* thd,

include/mysql/plugin_encryption.h.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@
281281
void *value;
282282
enum enum_mysql_show_type type;
283283
};
284-
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
284+
struct system_status_var;
285+
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
285286
struct st_mysql_sys_var;
286287
struct st_mysql_value;
287288
typedef int (*mysql_var_check_func)(void* thd,

include/mysql/plugin_ftparser.h.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@
281281
void *value;
282282
enum enum_mysql_show_type type;
283283
};
284-
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
284+
struct system_status_var;
285+
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
285286
struct st_mysql_sys_var;
286287
struct st_mysql_value;
287288
typedef int (*mysql_var_check_func)(void* thd,

include/mysql/plugin_password_validation.h.pp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@
281281
void *value;
282282
enum enum_mysql_show_type type;
283283
};
284-
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, enum enum_var_type);
284+
struct system_status_var;
285+
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
285286
struct st_mysql_sys_var;
286287
struct st_mysql_value;
287288
typedef int (*mysql_var_check_func)(void* thd,

libmysqld/lib_sql.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@ int init_embedded_server(int argc, char **argv, char **groups)
516516
if (my_thread_init())
517517
return 1;
518518

519+
if (init_early_variables())
520+
return 1;
521+
519522
if (argc)
520523
{
521524
argcp= &argc;

sql/mysqld.cc

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3997,35 +3997,31 @@ extern "C" {
39973997
static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
39983998
{
39993999
THD *thd= current_thd;
4000-
/* If thread specific memory */
4001-
if (likely(is_thread_specific))
4000+
4001+
if (likely(is_thread_specific)) /* If thread specific memory */
40024002
{
4003-
if (mysqld_server_initialized || thd)
4004-
{
4005-
/*
4006-
THD may not be set if we are called from my_net_init() before THD
4007-
thread has started.
4008-
However, this should never happen, so better to assert and
4009-
fix this.
4010-
*/
4011-
DBUG_ASSERT(thd);
4012-
if (thd)
4013-
{
4014-
DBUG_PRINT("info", ("memory_used: %lld size: %lld",
4015-
(longlong) thd->status_var.local_memory_used,
4016-
size));
4017-
thd->status_var.local_memory_used+= size;
4018-
DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0);
4019-
}
4020-
}
4003+
/*
4004+
When thread specfic is set, both mysqld_server_initialized and thd
4005+
must be set
4006+
*/
4007+
DBUG_ASSERT(mysqld_server_initialized && thd);
4008+
4009+
DBUG_PRINT("info", ("thd memory_used: %lld size: %lld",
4010+
(longlong) thd->status_var.local_memory_used,
4011+
size));
4012+
thd->status_var.local_memory_used+= size;
4013+
DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0);
40214014
}
40224015
else if (likely(thd))
4016+
{
4017+
DBUG_PRINT("info", ("global thd memory_used: %lld size: %lld",
4018+
(longlong) thd->status_var.global_memory_used,
4019+
size));
40234020
thd->status_var.global_memory_used+= size;
4021+
}
40244022
else
40254023
{
4026-
// workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
4027-
int64 volatile * volatile ptr=&global_status_var.global_memory_used;
4028-
my_atomic_add64_explicit(ptr, size, MY_MEMORY_ORDER_RELAXED);
4024+
update_global_memory_status(size);
40294025
}
40304026
}
40314027
}
@@ -4066,6 +4062,22 @@ rpl_make_log_name(const char *opt,
40664062
DBUG_RETURN(NULL);
40674063
}
40684064

4065+
/* We have to setup my_malloc_size_cb_func early to catch all mallocs */
4066+
4067+
static int init_early_variables()
4068+
{
4069+
if (pthread_key_create(&THR_THD, NULL))
4070+
{
4071+
fprintf(stderr, "Fatal error: Can't create thread-keys\n");
4072+
return 1;
4073+
}
4074+
set_current_thd(0);
4075+
set_malloc_size_cb(my_malloc_size_cb_func);
4076+
global_status_var.global_memory_used= 0;
4077+
return 0;
4078+
}
4079+
4080+
40694081
static int init_common_variables()
40704082
{
40714083
umask(((~my_umask) & 0666));
@@ -4077,16 +4089,12 @@ static int init_common_variables()
40774089
connection_errors_peer_addr= 0;
40784090
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
40794091

4080-
if (pthread_key_create(&THR_THD,NULL) ||
4081-
pthread_key_create(&THR_MALLOC,NULL))
4092+
if (pthread_key_create(&THR_MALLOC,NULL))
40824093
{
40834094
sql_print_error("Can't create thread-keys");
40844095
return 1;
40854096
}
40864097

4087-
set_current_thd(0);
4088-
set_malloc_size_cb(my_malloc_size_cb_func);
4089-
40904098
init_libstrings();
40914099
tzset(); // Set tzname
40924100

@@ -5184,6 +5192,9 @@ static int init_server_components()
51845192
init_global_table_stats();
51855193
init_global_index_stats();
51865194

5195+
/* It's now safe to use thread specific memory */
5196+
mysqld_server_initialized= 1;
5197+
51875198
/* Allow storage engine to give real error messages */
51885199
if (ha_init_errors())
51895200
DBUG_RETURN(1);
@@ -5544,6 +5555,9 @@ int mysqld_main(int argc, char **argv)
55445555
sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
55455556
mysqld_server_started= mysqld_server_initialized= 0;
55465557

5558+
if (init_early_variables())
5559+
exit(1);
5560+
55475561
#ifdef HAVE_NPTL
55485562
ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
55495563
#endif
@@ -5846,9 +5860,6 @@ int mysqld_main(int argc, char **argv)
58465860
if (Events::init((THD*) 0, opt_noacl || opt_bootstrap))
58475861
unireg_abort(1);
58485862

5849-
/* It's now safe to use thread specific memory */
5850-
mysqld_server_initialized= 1;
5851-
58525863
if (WSREP_ON)
58535864
{
58545865
if (opt_bootstrap)
@@ -8260,15 +8271,16 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
82608271

82618272

82628273
static int show_memory_used(THD *thd, SHOW_VAR *var, char *buff,
8274+
struct system_status_var *status_var,
82638275
enum enum_var_type scope)
82648276
{
82658277
var->type= SHOW_LONGLONG;
82668278
var->value= buff;
82678279
if (scope == OPT_GLOBAL)
8268-
*(longlong*) buff= (global_status_var.local_memory_used +
8269-
global_status_var.global_memory_used);
8280+
*(longlong*) buff= (status_var->global_memory_used +
8281+
status_var->local_memory_used);
82708282
else
8271-
*(longlong*) buff= thd->status_var.local_memory_used;
8283+
*(longlong*) buff= status_var->local_memory_used;
82728284
return 0;
82738285
}
82748286

@@ -8697,7 +8709,9 @@ static int mysql_init_variables(void)
86978709
prepared_stmt_count= 0;
86988710
mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
86998711
bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
8700-
bzero((char *) &global_status_var, sizeof(global_status_var));
8712+
/* Clear all except global_memory_used */
8713+
bzero((char*) &global_status_var, offsetof(STATUS_VAR,
8714+
last_cleared_system_status_var));
87018715
opt_large_pages= 0;
87028716
opt_super_large_pages= 0;
87038717
#if defined(ENABLED_DEBUG_SYNC)
@@ -9931,6 +9945,7 @@ void refresh_status(THD *thd)
99319945

99329946
/* Reset thread's status variables */
99339947
thd->set_status_var_init();
9948+
thd->status_var.global_memory_used= 0;
99349949
bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var));
99359950
thd->start_bytes_received= 0;
99369951

sql/sql_class.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ THD::THD(bool is_wsrep_applier)
914914
*/
915915
THD *old_THR_THD= current_thd;
916916
set_current_thd(this);
917-
status_var.local_memory_used= status_var.global_memory_used= 0;
917+
status_var.local_memory_used= sizeof(THD);
918+
status_var.global_memory_used= 0;
918919
main_da.init();
919920

920921
/*
@@ -1636,6 +1637,8 @@ THD::~THD()
16361637
that memory allocation counting is done correctly
16371638
*/
16381639
set_current_thd(this);
1640+
if (!status_in_global)
1641+
add_status_to_global();
16391642

16401643
/* Ensure that no one is using THD */
16411644
mysql_mutex_lock(&LOCK_thd_data);
@@ -1698,13 +1701,14 @@ THD::~THD()
16981701
if (xid_hash_pins)
16991702
lf_hash_put_pins(xid_hash_pins);
17001703
/* Ensure everything is freed */
1704+
status_var.local_memory_used-= sizeof(THD);
17011705
if (status_var.local_memory_used != 0)
17021706
{
17031707
DBUG_PRINT("error", ("memory_used: %lld", status_var.local_memory_used));
17041708
SAFEMALLOC_REPORT_MEMORY(my_thread_dbug_id());
17051709
DBUG_ASSERT(status_var.local_memory_used == 0);
17061710
}
1707-
1711+
update_global_memory_status(status_var.global_memory_used);
17081712
set_current_thd(orig_thd == this ? 0 : orig_thd);
17091713
DBUG_VOID_RETURN;
17101714
}
@@ -1723,6 +1727,7 @@ THD::~THD()
17231727
other types are handled explicitely
17241728
*/
17251729

1730+
17261731
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
17271732
{
17281733
ulong *end= (ulong*) ((uchar*) to_var +
@@ -1742,12 +1747,17 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
17421747
to_var->binlog_bytes_written+= from_var->binlog_bytes_written;
17431748
to_var->cpu_time+= from_var->cpu_time;
17441749
to_var->busy_time+= from_var->busy_time;
1745-
to_var->local_memory_used+= from_var->local_memory_used;
17461750

17471751
/*
17481752
Update global_memory_used. We have to do this with atomic_add as the
17491753
global value can change outside of LOCK_status.
17501754
*/
1755+
if (to_var == &global_status_var)
1756+
{
1757+
DBUG_PRINT("info", ("global memory_used: %lld size: %lld",
1758+
(longlong) global_status_var.global_memory_used,
1759+
(longlong) from_var->global_memory_used));
1760+
}
17511761
// workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
17521762
int64 volatile * volatile ptr= &to_var->global_memory_used;
17531763
my_atomic_add64_explicit(ptr, from_var->global_memory_used,

sql/sql_class.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,20 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
822822
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
823823
STATUS_VAR *dec_var);
824824

825+
/*
826+
Update global_memory_used. We have to do this with atomic_add as the
827+
global value can change outside of LOCK_status.
828+
*/
829+
inline void update_global_memory_status(int64 size)
830+
{
831+
DBUG_PRINT("info", ("global memory_used: %lld size: %lld",
832+
(longlong) global_status_var.global_memory_used,
833+
size));
834+
// workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
835+
int64 volatile * volatile ptr= &global_status_var.global_memory_used;
836+
my_atomic_add64_explicit(ptr, size, MY_MEMORY_ORDER_RELAXED);
837+
}
838+
825839
/**
826840
Get collation by name, send error to client on failure.
827841
@param name Collation name
@@ -3836,9 +3850,11 @@ class THD :public Statement,
38363850

38373851
void add_status_to_global()
38383852
{
3853+
DBUG_ASSERT(status_in_global == 0);
38393854
mysql_mutex_lock(&LOCK_status);
38403855
add_to_status(&global_status_var, &status_var);
38413856
/* Mark that this THD status has already been added in global status */
3857+
status_var.global_memory_used= 0;
38423858
status_in_global= 1;
38433859
mysql_mutex_unlock(&LOCK_status);
38443860
}

0 commit comments

Comments
 (0)