Bug #35477 sort_union() leaks file descriptors whenever goes over sort_buffer
| Submitted: | 21 Mar 2008 11:10 | Modified: | 1 May 2008 1:52 |
|---|---|---|---|
| Reporter: | Domas Mituzas | Email Updates: | |
| Status: | Duplicate | Impact on me: | |
| Category: | MySQL Server: General | Severity: | S2 (Serious) |
| Version: | 5.0-bk, 5.1.24, 6.0 | OS: | Any |
| Assigned to: | Assigned Account | CPU Architecture: | Any |
| Tags: | fd leak, memory leak | ||
[21 Mar 2008 11:18]
Domas Mituzas
example dump file
Attachment: jtest.sql.gz (application/x-gzip, text), 465.77 KiB.
[21 Mar 2008 11:22]
Domas Mituzas
This bug got a brother at #35478 - it also returns invalid data
[26 Mar 2008 23:43]
Domas Mituzas
My amateurish fix, seems to handle the situation without too much crashing, and doesn't leak FDs. Bug#35478 still there, though: flute:~/Development/mysql-5.0/sql midom$ diff -U 7 filesort.cc filesort.cc.fixed --- filesort.cc 2008-03-27 01:41:17.000000000 +0200 +++ filesort.cc.fixed 2008-03-27 01:41:08.000000000 +0200 @@ -553,14 +553,15 @@ if (quick_select) { /* index_merge quick select uses table->sort when retrieving rows, so free resoures it has allocated. */ end_read_record(&read_record_info); + free_io_cache(select->quick->head); } else { (void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */ if (!next_pos) file->ha_rnd_end(); }
[27 Mar 2008 6:20]
Domas Mituzas
patch seems to pass testsuite
[27 Mar 2008 9:34]
Domas Mituzas
This bug also leaks memory: ==18833== 66,073 (510 direct, 65,563 indirect) bytes in 6 blocks are definitely lost in loss record 6 of 7 ==18833== at 0x4022765: malloc (vg_replace_malloc.c:149) ==18833== by 0x831A874: my_malloc (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x8219CFF: Unique::get(st_table*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x824B166: QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x825B5AD: find_all_keys(st_sort_param*, SQL_SELECT*, unsigned char**, st_io_cache*, st_io_cache*, st_io_cache*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x825D7A8: filesort(THD*, st_table*, st_sort_field*, unsigned, SQL_SELECT*, unsigned long, unsigned long*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x81F56A4: create_sort_index(THD*, JOIN*, st_order*, unsigned long, unsigned long) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x8201904: JOIN::exec() (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x8203AE7: mysql_select(THD*, Item***, TABLE_LIST*, unsigned, List<Item>&, Item*, unsigned, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x820436E: handle_select(THD*, st_lex*, select_result*, unsigned long) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x81AC028: mysql_execute_command(THD*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x81B14BB: mysql_parse(THD*, char const*, unsigned, char const**) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== ==18833== ==18833== 818,984 bytes in 4 blocks are possibly lost in loss record 7 of 7 ==18833== at 0x4022765: malloc (vg_replace_malloc.c:149) ==18833== by 0x831A874: my_malloc (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x825AA8F: init_read_record(st_read_record*, THD*, st_table*, SQL_SELECT*, int, bool) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x824B1A9: QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x825B5AD: find_all_keys(st_sort_param*, SQL_SELECT*, unsigned char**, st_io_cache*, st_io_cache*, st_io_cache*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x825D7A8: filesort(THD*, st_table*, st_sort_field*, unsigned, SQL_SELECT*, unsigned long, unsigned long*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x81F56A4: create_sort_index(THD*, JOIN*, st_order*, unsigned long, unsigned long) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x8201904: JOIN::exec() (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x8203AE7: mysql_select(THD*, Item***, TABLE_LIST*, unsigned, List<Item>&, Item*, unsigned, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x820436E: handle_select(THD*, st_lex*, select_result*, unsigned long) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x81AC028: mysql_execute_command(THD*) (in /usr/local/mysql-5.0/libexec/mysqld) ==18833== by 0x81B14BB: mysql_parse(THD*, char const*, unsigned, char const**) (in /usr/local/mysql-5.0/libexec/mysqld)
[27 Mar 2008 9:39]
Domas Mituzas
slightly better formatted valgrind output at: http://p.defau.lt/?_ZxrNXcfnAPoKHSYrgqQSw
[27 Mar 2008 12:03]
Domas Mituzas
Fix for memory leak:
--- opt_range.cc 2008-03-27 08:03:13.000000000 -0400
+++ opt_range.cc.new 2008-03-27 08:03:04.000000000 -0400
@@ -1035,14 +1035,16 @@
QUICK_RANGE_SELECT* quick;
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
quick_it.rewind();
while ((quick= quick_it++))
quick->file= NULL;
quick_selects.delete_elements();
delete pk_quick_select;
+ if (&read_record)
+ end_read_record(&read_record);
free_root(&alloc,MYF(0));
DBUG_VOID_RETURN;
}
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
TABLE *table,
[4 Apr 2008 13:54]
Georgi Kodinov
Domas, I've tried with the latest 5.0-opt-bk and I'm not getting the effect (no leaked fds) even after repeating the query several times. But I'm probably missing something in recreating the problem. Can we please get a real test script (for mysqltest) that uses e.g. INSERT INTO t1 ... SELECT ... FROM t1 ... to generate data (as looking at your test data dump this seems doable) ?
[4 Apr 2008 14:35]
Shane Bester
Georgi, I haven't tested this, but you can try setting the lowest possible sort_buffer_size and see if it leaks then.
[10 Apr 2008 7:20]
Shane Bester
standalone testcase to show 20MB/s memory leak, and file handle leak -------------------------------------------------------------------- delimiter ; drop table if exists `bug35477`; create table `bug35477` (`a` varchar(255),`b` varchar(255),`c` varchar(255),key(`a`),key(`b`),key(`c`)) engine=myisam; insert into `bug35477`values ('1','2','3'),('4','5','6'),('7','8','9'); set @a=1,@b=1,@c=1; insert into `bug35477` select @a:=@a+1,@b:=@b+2,@c:=@c+3 from `bug35477` a,`bug35477` b,`bug35477` c; insert into `bug35477` select @a:=@a+1,@b:=@b+2,@c:=@c+3 from `bug35477` a,`bug35477` b,`bug35477` c; drop procedure if exists `p_bug35477`; delimiter // create procedure `p_bug35477`(`numtimes` int) begin declare `i` int default '0'; repeat select * from `bug35477` where `a` like '5%' or `b` like '5%' order by `c` limit 1 into @a,@b,@c; if(`i` % 100 =0) then select `i` as repetition; end if; set `i`=`i`+1; until `i`>`numtimes` end repeat; end// delimiter ; set session sort_buffer_size=1024; call `p_bug35477`(50000);
[10 Apr 2008 12:11]
Shane Bester
Georgi, if my above testcase doesn't repeat the problem on your internal BK builds, i wonder if this bug was fixed in bug #27732 (Possible memory leak with index_merge) ?
[10 Apr 2008 14:17]
Sergey Petrunya
Using 5.0-opt with tip cset: ChangeSet@1.2601, 2008-03-27 20:05:51+04:00, gshchepa@host.loc +2 -0 Merge host.loc:/home/uchum/work/mysql-5.0 into host.loc:/home/uchum/work/5.0-opt MERGE: 1.2599.1.2 (i.e. BUG#27732 is in the tree), I still can see the fd leaks.
[10 Apr 2008 14:42]
Sergey Petrunya
Can observe leaks on the latest 6.0 opt also. tip cset: ChangeSet@1.2604, 2008-04-07 13:21:26-06:00, malff@lambda.hsd1.co.comcast.net. +1 -0 Merge malff@bk-internal.mysql.com:/home/bk/mysql-5.0-opt into lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.0-35658 MERGE: 1.2598.5.1
[10 Apr 2008 14:43]
Sergey Petrunya
The above two observations were made by using Domas's testcase
[21 Apr 2008 4:21]
Sergey Petrunya
The fix is at http://lists.mysql.com/commits/45739
[1 May 2008 1:52]
Sergey Petrunya
Fixed by fix for BUG#35478. Changing status to duplicate.
[22 Jul 2008 18:36]
Bugs System
Pushed into 5.0.68
[28 Jul 2008 13:46]
Bugs System
Pushed into 5.0.68 (revid:kpettersson@mysql.com-20080716141220-83aobe5fdgd9ye5l) (pib:2) (Retry automatic marking, to ensure nothing is missed. cm01)
[28 Jul 2008 14:45]
Bugs System
Pushed into 6.0.7-alpha (revid:alik@mysql.com-20080725172155-fnc73o50e4tgl23k) (version source revid:alik@mysql.com-20080725172155-fnc73o50e4tgl23k) (pib:3)
[28 Jul 2008 16:44]
Bugs System
Pushed into 5.1.28 (revid:davi.arnaut@sun.com-20080722182431-0i2f1yc4uocime9q) (version source revid:davi.arnaut@sun.com-20080722182431-0i2f1yc4uocime9q) (pib:3)
[14 Sep 2008 2:21]
Bugs System
Pushed into 6.0.7-alpha (revid:sergefp@mysql.com-20080715141321-2vlk93j5blqa7kxe) (version source revid:sven@mysql.com-20080818195835-r615g9zz6xphmkzg) (pib:3)
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.095 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: whenever sort_union() is used, and sort_buffer_size is reached, temporary files are leaked: mysqld 3988 mysql 122u REG 14,2 78654 16999463 /private/var/tmp/MY69MtDm mysqld 3988 mysql 123u REG 14,2 78654 16999469 /private/var/tmp/MYuUS218 mysqld 3988 mysql 124u REG 14,2 78654 16999475 /private/var/tmp/MYXTIgLK mysqld 3988 mysql 125u REG 14,2 78654 16999481 /private/var/tmp/MYhnvrNz mysqld 3988 mysql 126u REG 14,2 78654 16999487 /private/var/tmp/MYXAYcoG mysqld 3988 mysql 127u REG 14,2 78654 16999493 /private/var/tmp/MYhOGRAZ mysqld 3988 mysql 128u REG 14,2 78654 16999499 /private/var/tmp/MY1RLE4Q mysqld 3988 mysql 129u REG 14,2 78654 16999505 /private/var/tmp/MYwXVR6D mysqld 3988 mysql 130u REG 14,2 78654 16999511 /private/var/tmp/MYh8SGBC How to repeat: CREATE TABLE `jtest` ( `a` varchar(255) default NULL, `b` varchar(255) default NULL, `c` varchar(255) default NULL, KEY `a` (`a`), KEY `b` (`b`), KEY `c` (`c`) ) ENGINE=MyISAM fill with few megabytes of random data, so that hitting sort buffer problems would be easier set sort_buffer_size=10000; then loop: select * from jtest where a like '5%' or b like '5%' order by c limit 1; mysql> explain select * from jtest where a like '5%' or b like '5%' order by c limit 1 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: jtest type: index_merge possible_keys: a,b key: a,b key_len: 258,258 ref: NULL rows: 23746 Extra: Using sort_union(a,b); Using where; Using filesort 1 row in set (0.00 sec) Suggested fix: close the files?