Bug #70238 Memory leak in embedded server when executing prepared statements
| Submitted: | 4 Sep 2013 6:42 | Modified: | 6 Sep 2017 9:03 |
|---|---|---|---|
| Reporter: | Feng Guangpu | Email Updates: | |
| Status: | Can't repeat | Impact on me: | |
| Category: | MySQL Server: Prepared statements | Severity: | S2 (Serious) |
| Version: | 5.6.11, 5.6.15 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | embedded, libmysqld, memory leak | ||
[4 Sep 2013 6:54]
Feng Guangpu
libmysqld_prepare_statement.c
Attachment: libmysqld_prepared_statement.c (application/octet-stream, text), 3.20 KiB.
[4 Sep 2013 6:55]
Feng Guangpu
contents of my_embedded.cnf: [client] socket = /u01/mysql5611/run/mysql.sock [embedded] sort_buffer_size=1M core-file #### Baes dir #### basedir = /u01/mysql5611 datadir = /u01/mysql5611/data_embedded tmpdir = /u01/mysql5611/tmp_embedded socket = /u01/mysql5611/run_embedded/mysql.sock #### Base configure info #### port = 5611 skip-name-resolve old_passwords = 0 lower_case_table_names = 1 open_files_limit = 65535 read_rnd_buffer_size = 5M max_allowed_packet = 24M max_connect_errors = 500 max_connections = 5 max_user_connections = 4 thread_cache_size=2 table_open_cache=16 table_definition_cache=8 server-id= 5611 #innodb innodb_data_home_dir = /u01/mysql5611/data_embedded default-storage-engine = INNODB innodb_flush_method = O_DIRECT innodb_file_per_table = 1 innodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 100 innodb_additional_mem_pool_size = 4M innodb_buffer_pool_size = 64M innodb_log_buffer_size= 8M innodb_log_file_size = 16M innodb_log_files_in_group = 4 innodb_max_dirty_pages_pct = 75 thread_stack = 1524288 [mysqld_safe] pid-file = /u01/mysql5611/run_embedded/mysqld.pid
[4 Sep 2013 8:25]
Feng Guangpu
in mysql_stmt_init ... init_alloc_root(&stmt->mem_root, 2048, 2048); // line 1512 init_alloc_root(&stmt->result.alloc, 4096, 4096);// line 1513 ... ==29639== 2,064 bytes in 1 blocks are definitely lost in loss record 3 of 4 ==29639== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==29639== by 0x4635E1: my_malloc (my_malloc.c:38) ==29639== by 0x462C72: init_alloc_root (my_alloc.c:63) ==29639== by 0x448935: mysql_stmt_init (libmysql.c:1512) ==29639== by 0x444277: main (in /u01/mysql5611/bug62136) 2064 bytes come from: 2048 + sizeof(USED_MEM) ==29639== 4,112 bytes in 1 blocks are definitely lost in loss record 4 of 4 ==29639== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==29639== by 0x4635E1: my_malloc (my_malloc.c:38) ==29639== by 0x462C72: init_alloc_root (my_alloc.c:63) ==29639== by 0x44894B: mysql_stmt_init (libmysql.c:1513) ==29639== by 0x444277: main (in /u01/mysql5611/bug62136) 4112 bytes come from: 4096 + sizeof(USED_MEM)
[8 Jan 2014 10:05]
MySQL Verification Team
Hello Guangpu, Thank you for the bug report and test case. Thanks, Umesh
[6 Sep 2017 9:03]
Manyi Lu
Posted by developer: Embedded mode has already been removed starting from 8.0.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.057 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: The embedded server leaks memeory when executing perpared statements part of the valgrind output: ==29639== 2,064 bytes in 1 blocks are definitely lost in loss record 3 of 4 ==29639== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==29639== by 0x4635E1: my_malloc (my_malloc.c:38) ==29639== by 0x462C72: init_alloc_root (my_alloc.c:63) ==29639== by 0x448935: mysql_stmt_init (libmysql.c:1512) ==29639== by 0x444277: main (in /u01/mysql5611/bug62136) ==29639== ==29639== 4,112 bytes in 1 blocks are definitely lost in loss record 4 of 4 ==29639== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==29639== by 0x4635E1: my_malloc (my_malloc.c:38) ==29639== by 0x462C72: init_alloc_root (my_alloc.c:63) ==29639== by 0x44894B: mysql_stmt_init (libmysql.c:1513) ==29639== by 0x444277: main (in /u01/mysql5611/bug62136) ==29639== ==29639== LEAK SUMMARY: ==29639== definitely lost: 6,176 bytes in 2 blocks ==29639== indirectly lost: 0 bytes in 0 blocks ==29639== possibly lost: 0 bytes in 0 blocks ==29639== still reachable: 568 bytes in 2 blocks ==29639== suppressed: 0 bytes in 0 blocks ==29639== ==29639== For counts of detected and suppressed errors, rerun with: -v ==29639== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 6) the reason is that the assignments of stmt->mem_root in emb_read_prepare_result and stmt->result in emb_read_binary_rows without freeing the memory in MEM_ROOT. libmysqd/lib_sql.cc line 263: 251 if (thd->first_data) 252 { 253 if (emb_read_query_result(mysql)) 254 return 1; 255 stmt->field_count= mysql->field_count; 256 mysql->status= MYSQL_STATUS_READY; 257 res= thd->cur_data; 258 thd->cur_data= NULL; 259 if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) 260 mysql->server_status|= SERVER_STATUS_IN_TRANS; 261 262 stmt->fields= mysql->fields; 263 stmt->mem_root= res->alloc; 264 mysql->fields= NULL; 265 my_free(res); 266 } line 365: 357 int emb_read_binary_rows(MYSQL_STMT *stmt) 358 { 359 MYSQL_DATA *data; 360 if (!(data= emb_read_rows(stmt->mysql, 0, 0))) 361 { 362 set_stmt_errmsg(stmt, &stmt->mysql->net); 363 return 1; 364 } 365 stmt->result= *data; 366 my_free(data); 367 set_stmt_errmsg(stmt, &stmt->mysql->net); 368 return 0; 369 } How to repeat: Test program will be attached, see the first comment. Suggested fix: --- libmysqld/lib_sql.cc (revision 4360) +++ libmysqld/lib_sql.cc (working copy) @@ -260,7 +260,6 @@ mysql->server_status|= SERVER_STATUS_IN_TRANS; stmt->fields= mysql->fields; - stmt->mem_root= res->alloc; mysql->fields= NULL; my_free(res); } @@ -362,6 +361,7 @@ set_stmt_errmsg(stmt, &stmt->mysql->net); return 1; } + free_root(&(stmt->result.alloc), MYF(0)); stmt->result= *data; my_free(data); set_stmt_errmsg(stmt, &stmt->mysql->net); [No-Mysql@db031133.sqa.cm4 /u01/mysql_prj/PS5518/branches/mysql-5.6.11]