我在MySQL中有大量的打开的文件限制。
我已经将open_files_limit设置为150000,但是MySQL仍然使用了将近80% 。
另外我有低stream量和最大并发连接30左右,没有查询有超过4个连接。
服务器打开的文件在performance_schema中可见。
请参阅表performance_schema.file_instances。
http://dev.mysql.com/doc/refman/5.5/en/file-instances-table.html
至于跟踪哪个查询打开哪个文件,由于缓存在服务器本身(表缓存,表定义缓存)中,它不会以这种方式工作。
这只能通过调整源代码并在该级别上添加日志记录来实现。
备选:使用此方案运行测试:
你将不得不建立一个自动化的测试,使之成为可能:
我个人会开始不同的:
MySQL不应该打开那么多的文件,除非你为table_cache
参数设置了一个非常大的值(默认是64,最大值是512K)。
您可以通过发出FLUSH TABLES
命令来减少打开文件的数量。
否则,可以通过针对所有MySQLd线程运行strace -c
粗略估计table_cache
的适当值(在Linux中)。 你得到像这样的东西:
# strace -f -c -p $( pidof mysqld ) Process 13598 attached with 22 threads [ ...pause while it gathers information... ] ^C Process 13598 detached ... % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 58.82 0.040000 51 780 io_getevents 29.41 0.020000 105 191 93 futex 11.76 0.008000 103 78 select 0.00 0.000000 0 72 stat 0.00 0.000000 0 20 lstat 0.00 0.000000 0 16 lseek 0.00 0.000000 0 16 read 0.00 0.000000 0 9 3 open 0.00 0.000000 0 5 close 0.00 0.000000 0 6 poll ... ------ ----------- ----------- --------- --------- ----------------
…看看在open()和close()调用中是否有合理的影响差异; 这些是table_cache
影响的调用,并影响在任何给定点上有多少打开的文件。
如果open()
的影响可以忽略不计,那么一定要减少table_cache
。 这是主要的慢IOSS'es,并没有太多的左边。
如果你在Windows上运行,你将不得不尝试使用SysInternals的ProcMon或者类似的工具 。
一旦你有table_cache
到可管理的级别,你的查询,现在打开太多的文件将关闭并重新打开许多这些相同的文件。 你可能会注意到对性能的影响,这很可能是微不足道的。 机会是,一个较小的表缓存实际上可以让你的结果更快 ,因为从一个现代的,快速的IOSS缓存中获取一个项目可能会比在一个非常大的缓存中搜索项目更快。
如果你正在优化你的服务器,你也可以看看这篇文章 。 外带是随着缓存的增加, 大的并不总是更好 (这也适用于索引)。
在Linux上,您可以使用strace (请参阅上文),并验证打开了哪些文件以及如何:
$ sudo strace -f -p $( pidof mysqld ) 2>&1 | grep 'open("'
同时从不同的终端运行查询,并且:
[pid 8894] open("./ecm/db.opt", O_RDONLY) = 39 [pid 8894] open("./ecm/prof2_people.frm", O_RDONLY) = 39 [pid 8894] open("./ecm/prof2_discip.frm", O_RDONLY) = 39 [pid 8894] open("./ecm/prof2_discip.ibd", O_RDONLY) = 19 [pid 8894] open("./ecm/prof2_discip.ibd", O_RDWR) = 19 [pid 8894] open("./ecm/prof2_people.ibd", O_RDONLY) = 20 [pid 8894] open("./ecm/prof2_people.ibd", O_RDWR) = 20 [pid 8894] open("/proc/sys/vm/overcommit_memory", O_RDONLY|O_CLOEXEC) = 39
…这些是查询使用的文件(*确保在“冷启动”MySQL上运行查询以防止缓存),并且我看到分配的最高文件句柄是39,因此在那里没有超过40个打开的文件。
可以从/ proc / $ PID / fd或从MySQL中检查相同的文件:
select * from performance_schema.file_instances where open_count > 1;
但是MySQL的计数稍微短一点,它不考虑套接字描述符,日志文件和临时文件。