Bug #57480 | Memory leak when having 256+ tables | ||
---|---|---|---|
Submitted: | 15 Oct 2010 11:19 | Modified: | 5 Jan 2012 1:22 |
Reporter: | Alexander Rubin | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 5.1, 5.0 | OS: | Any |
Assigned to: | Vasil Dimov | CPU Architecture: | Any |
Tags: | memory leak, partitioning |
[15 Oct 2010 11:19]
Alexander Rubin
[15 Oct 2010 15:41]
Mattias Jonsson
Could it be related to bug#20877? Test to create 256+ tables instead and access them and see if you get the same result.
[17 Oct 2010 11:21]
Alexander Rubin
Yes, it is growing with 256 tables, without partitioning. Test case with 256 tables: # create 256 tables like the original one and load 40K rows in each for i in {1..256}; do echo "drop table if exists sbtest$i; create table sbtest$i like sbtest; insert into sbtest$i select * from sbtest limit 40000" | /data1/arubin/mysql51/bin/mysql -vvv -h 127.0.0.1 -uroot -P3309 -A sbtest; done sql="select count(id) from sbtest1 as s$i" # generate SQL with union for i in {2..256}; do sql="$sql union select id from sbtest$i as s$i"; done echo $sql # run count(*) on top of union for i in {1..256}; do echo "select count(*) from ($sql) as a" | /data1/arubin/mysql51/bin/mysql -h 127.0.0.1 -uroot -P3309 -A sbtest & done Regarding InnoDB dict: Total memory allocated 4391436288; in additional pool allocated 0 Dictionary memory allocated 1291612 Buffer pool size 262143 Free buffers 4 Database pages 262136 Old database pages 96745 Modified db pages 0 Pending reads 0 So, it is only allocated 1M
[16 Nov 2010 0:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".
[5 Jan 2011 21:36]
Alexander Rubin
This happens with 256 tables, not related specifically to partitions. Here are the top snapshots during the select count(*) execution. This is 256 tables, not partitions Before: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9232 arubin 16 0 4717m 423m 5720 S 0 5.4 27:39.78 mysqld During execution: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9232 arubin 16 0 5162m 877m 5812 S 319 11.2 27:51.83 mysqld PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9232 arubin 16 0 6208m 1.8g 5812 S 397 23.5 34:16.32 mysqld PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9232 arubin 16 0 6258m 1.9g 5812 S 396 24.4 43:02.82 mysqld PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9232 arubin 16 0 6490m 2.2g 5824 S 0 29.4 95:32.10 mysqld mysql> flush tables; Query OK, 0 rows affected (0.01 sec) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9232 arubin 16 0 6490m 2.2g 5836 S 0 29.4 95:32.20 mysqld So, flush tables does not release memory
[8 Jan 2011 23:12]
Alexander Rubin
hpof with mysqldebug results during the script execution pprof /data1/arubin/mysql51/bin/mysqld /tmp/mysql.hprof_6659.0010.heap Total: 5228.6 MB 4723.1 90.3% 90.3% 4723.1 90.3% dict_create 505.3 9.7% 100.0% 505.3 9.7% handle_options 0.1 0.0% 100.0% 0.1 0.0% __GI__dl_allocate_tls pprof /data1/arubin/mysql51/bin/mysqld /tmp/mysql.hprof_6659.0019.heap Total: 6121.8 MB 4833.2 78.9% 78.9% 4833.2 78.9% dict_create 1288.5 21.0% 100.0% 1288.5 21.0% handle_options 0.1 0.0% 100.0% 0.1 0.0% __GI__dl_allocate_tls 0.1 0.0% 100.0% 0.1 0.0% my_well_formed_len_8bit
[9 Jan 2011 15:23]
Alexander Rubin
MySQL 5.5: Total: 1910.9 MB 1362.8 71.3% 71.3% 1362.8 71.3% vtable for Item_sum_udf_str 323.0 16.9% 88.2% 323.0 16.9% update_auto_increment_key 216.9 11.4% 99.6% 216.9 11.4% row_ins 4.1 0.2% 99.8% 4.1 0.2% vtable for Item_func_char_length mysqladmin debug status: Memory status: Non-mmapped space allocated from system: -2097778688 Number of free chunks: 0 Number of fastbin blocks: 0 Number of mmapped regions: 0 Space in mmapped regions: 0 Maximum total allocated space: 0 Space available in freed fastbin blocks: 8937488 Total allocated space: 313540592 Total free space: 1874710528 Top-most, releasable space: 0 Estimated memory (with thread stack): -2097778688 But memory is still growing: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 25844 arubin 15 0 6966m 4.5g 6304 S 334 59.2 141:26.56 mysqld-debug
[9 Jan 2011 15:59]
Alexander Rubin
MySQL 5.5 after 2 times script run: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 25844 arubin 15 0 7033m 4.6g 6304 S 0 60.2 273:47.58 mysqld-debug
[3 Feb 2011 16:59]
Mikhail Izioumtchenko
not obvious that this is InnoDB and not partitioning in general. What would help, is pmap and pstack, or the equivalent, output for the mysqld process, every 2-5 seconds, when you are see the memory leak.
[23 Jun 2011 5:21]
MySQL Verification Team
I still fail to see any bug here at all. The testcase is highly concurrent. Can you determine if the problem is: 1) number of tables in the test or 2) number of threads running concurrently or 3) combination of the threads + tables.
[13 Jul 2011 9:02]
Thomas Parrott
I have a database with over 35,000 partitions across 120 databases, and I am seeing a memory leak since 5.5.8, and including 5.5.14. Please see issue #61829
[23 Nov 2011 23:37]
James Day
Very extensive work has been done on this, not yet ready for release though. Among other things the work has included: 1. Moving many allocations to the heap instead of malloc. 2. Merging multiple allocations into one in several cases. 3. Better estimates of sizes needed for some allocations. 4. Defer allocation of upd_buff, of the size of the data row, that's only needed if a row is updated.
[26 Nov 2011 1:17]
James Day
One correction to my last post: 1. Moving many allocations to the stack instead of malloc.
[21 Dec 2011 17:22]
Davy Verstappen
Just a suggestion: The Redis NoSQL in-memory database uses jemalloc on Linux (from their README file): "Redis is compiled and linked against libc malloc by default, with the exception of jemalloc being the default on Linux systems. This default was picked because jemalloc has proven to have fewer fragmentation problems than libc malloc." If you don't want to recompile mysql with jemalloc, you can probably compile jemalloc as a shared library, and then use the LD_PRELOAD environment variable, so it gets loaded before the libc malloc implementation.
[5 Jan 2012 1:22]
John Russell
Adding to changelog: Memory allocation for InnoDB tables was reorganized to reduce the memory overhead for large numbers of tables or partitions, avoiding situations where the "resident set size" could grow regardless of FLUSH TABLES statements. The problem was most evident for tables with large row size. Some of the memory that was formerly allocated for every open table is now allocated only when the table is modified for the first time.
[21 Jan 2012 0:59]
James Day
There are two Transactions on InnoDB blog entries discussing the memory allocation improvements prompted by this report: http://blogs.innodb.com/wp/2011/12/improving-innodb-memory-usage/ http://blogs.innodb.com/wp/2011/12/improving-innodb-memory-usage-continued/ While the big improvement in reduced fragmentation comes with the Linux memory allocator the general improvement in efficiency and deferring of some memory allocations until they are needed should help other operating systems.
[26 Jan 2012 16:14]
Calvin Sun
The fix has been backported to 5.5. Will be in 5.5.21 release. Thanks!
[13 Sep 2014 16:19]
James Day
The fix for this bug introduced bug #70641 "5.6 partitions use much more memory than 5.1".