Description:
When too many file handles are used, MySQL returns a miss-leading error:
Error 1037 Out of memory; restart server and try again (needed 2 bytes)
How to repeat:
It is difficult to reproduce, but should be possible to repeat with the following test:
create table t1 (a int, b int)
partition by list(a) subpartition by hash(b) subpartitions 20
(
partition p0 values in (0),
partition p1 values in (1),
partition p2 values in (2),
partition p3 values in (3)
);
insert into t1 values (1,1),(2,2),(3,3);
Before running the test set the number of file handles very low, e.g:
ulimit -n 20
The error occurs with the following stack trace:
#0 my_open (FileName=0xb00e0d40 "./test/t1.par", Flags=-1341256384, MyFlags=3) at my_open.c:70
#1 0x0015b4c2 in ha_partition::get_from_handler_file (this=0x1730210, name=0x172f4e0 "./test/t1", mem_root=0x172f2dc) at ha_partition.cc:2319
#2 0x0015da8f in ha_partition::initialise_partition (this=0x1730210, mem_root=0x172f2dc) at ha_partition.cc:355
#3 0x0015f6cb in partition_create_handler (hton=0x901c80, share=0x172f2a4, mem_root=0x172f2dc) at ha_partition.cc:110
#4 0x00158a8e in get_new_handler (share=0xb00e0d40, alloc=0xb00e0d40, db_type=0x901c80) at handler.cc:246
#5 0x000e2026 in open_table_def (thd=0x1031000, share=0x172f2a4, db_flags=0) at table.cc:1101
my_open() fails with the error "too many file handles open" if:
if ((uint) fd >= my_file_limit)
in my_register_filename() which is called from my_open().
[ NOTE: in this case, the fd which is valid is not closed (it is simply discarded), here is the code:
if ((uint) fd >= my_file_limit)
{
#if defined(THREAD) && !defined(HAVE_PREAD)
my_errno= EMFILE;
#else
thread_safe_increment(my_file_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
#endif
}
else
{
....
On my mac HAVE_PREAD is not defined so "my_errno= EMFILE" is executed although the file handle is valid! This valid file handle is not closed. ]
After fopen() returns an error, get_from_handler_file() executes the following code:
else if (get_from_handler_file(table_share->normalized_path.str, mem_root))
{
mem_alloc_error(2);
DBUG_RETURN(1);
}
In ha_partition.cc line 355. The "Out of memory" appears in the server error log.
So the original reason for the error "too many file handles open" is not reported.