(转)MySQL open_files_limit相关设置
背景:
数据库链接不上,报错:
- root@localhost:/var/log/mysql# mysql -uzjy -p -h192.168.1.111 --default-character-set=utf8 -P3306
- Enter password:
- ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
分析方法:
在这个地方我看不出什么,直接看错误日志:
- [ERROR] /usr/sbin/mysqld: Can't open file: './java/tt_fte.frm' (errno: 24)
- root@localhost:/var/log/mysql# perror 24
- OS error code 24: Too many open files
一看到这里,就觉得需要调整 open_files_limit 参数了(默认最小1024),至此问题解决。虽然问题解决了,但是还没有弄清楚MySQL打开了多少个文件描述符,打开了哪写文件描述符号,以及如何预防。怎么了解MySQL打开了多少个文件描述符呢?
知识点:用lsof去查看,理解myisam和innodb的文件描述符、OS 的ulimit相关认识。
基于上面的问题,现在来分析(此时数据库就连不上了,一直报无法打开的错误信息)查看MySQL打开的文件:

- root@localhost:~# lsof -p 26288 | wc -l
- 1042
- #因为数据库链接不了,所以只能通过系统查看他的文件描述符
- root@localhost:~# cat /proc/26288/limits
- Limit Soft Limit Hard Limit Units
- Max cpu time unlimited unlimited seconds
- Max file size unlimited unlimited bytes
- Max data size unlimited unlimited bytes
- Max stack size 8388608 unlimited bytes
- Max core file size 0 unlimited bytes
- Max resident set unlimited unlimited bytes
- Max processes 79877 79877 processes
- Max open files 1024 4096 files
- Max locked memory 65536 65536 bytes
- Max address space unlimited unlimited bytes
- Max file locks unlimited unlimited locks
- Max pending signals 79877 79877 signals
- Max msgqueue size 819200 819200 bytes
- Max nice priority 0 0
- Max realtime priority 0 0
- Max realtime timeout unlimited unlimited us
- 也可以通过下面的方法查看,下面的方法最为精确
root@localhost:~# ls -lh /proc/26288/fd | wc -l
1024

上面看出,MySQL这时打开的文件描述符1024,已经达到上限,所以再打开的时候就报错了。修改open_files_limit 参数,设置为2000试试?

- root@localhost:~# lsof -p 27732 | wc -l
- 1053
- root@localhost:~# cat /proc/27732/limits
- Limit Soft Limit Hard Limit Units
- Max cpu time unlimited unlimited seconds
- Max file size unlimited unlimited bytes
- Max data size unlimited unlimited bytes
- Max stack size 8388608 unlimited bytes
- Max core file size 0 unlimited bytes
- Max resident set unlimited unlimited bytes
- Max processes 79877 79877 processes
- Max open files 2000 2000 files
- Max locked memory 65536 65536 bytes
- Max address space unlimited unlimited bytes
- Max file locks unlimited unlimited locks
- Max pending signals 79877 79877 signals
- Max msgqueue size 819200 819200 bytes
- Max nice priority 0 0
- Max realtime priority 0 0
- Max realtime timeout unlimited unlimited us
- root@localhost:~# ls -lh /proc/27732/fd | wc -l
- 1035

上面看出,MySQL需要打开的文件描述符1035,小于2000,数据库正常。到此为止,上面的问题得到解决。想更清楚了解的请继续看:
查看数据库的变量:

- zjy@localhost : (none) 10:27:19>show global status like 'open%';
- +--------------------------+-------+
- | Variable_name | Value |
- +--------------------------+-------+
- | Open_files | 804 |
- | Open_streams | 0 |
- | Open_table_definitions | 400 |
- | Open_tables | 400 |
- | Opened_files | 6803 |
- | Opened_table_definitions | 3861 |
- | Opened_tables | 4315 |
- +--------------------------+-------+
- 7 rows in set (0.00 sec)
- zjy@localhost : (none) 10:31:11>show global variables like 'open%';
- +------------------+-------+
- | Variable_name | Value |
- +------------------+-------+
- | open_files_limit | 2000 |
- +------------------+-------+
- 1 row in set (0.00 sec)
- zjy@localhost : (none) 10:39:03>show global variables like 'table_open_cache';
- +------------------+-------+
- | Variable_name | Value |
- +------------------+-------+
- | table_open_cache | 400 |
- +------------------+-------+
- 1 row in set (0.00 sec)

在MySQL 5.1.3之后,还添加了2个状态值:Open_table_definitions和Opened_table_definitions。这2个值代表的意思如下:
Open_table_definitions :代表当前缓存了多少.frm文件。
Opened_table_definitions:代表自从MySQL启动后,缓存了.frm文件的数量。 需要注意的是.frm文件是MySQL用于存放表结构的文件,对应myisam和innodb存储引擎都必须有的,可以通过show open tables 查看 这2个变量的值。
说到这里主要关注的参数还是:table_open_cache 其作用是:从MySQL5.1.3 开始改为table_open_cache,所有线程所打开表的数量, 增加此值就增加了mysqld所需要的文件描述符的数量.它的作用就是缓存表文件描述符,降低打开关闭表的频率, 如果这个参数设置得过小,那么很快就会被占满,再有新请求过来的时候,就不得不关闭一些已打开的表以便为新请求腾出空间,从而出现频繁的打开关闭MyISAM表文件的情况,而INNODB表的打开 不受这个参数控制,而是放到其数据字典当中,即在ibd中。
查看打开的各个文件描述符是什么:大部分都是MYI,MYD,IBD文件。

- root@localhost:/proc/27732/fd# ls -lh | grep MYI | wc -l
- 400
- root@localhost:/proc/27732/fd# ls -lh | grep MYD | wc -l
- 400
- root@localhost:/proc/27732/fd# ls -lh | grep ibd | wc -l
- 215
- root@localhost:/proc/27732/fd# lsof | grep /var/lib/mysql | grep MYI | wc -l
- 400
- root@localhost:/proc/27732/fd# lsof | grep /var/lib/mysql | grep MYD | wc -l
- 400
- root@localhost:/proc/27732/fd# lsof | grep /var/lib/mysql | grep '\.ibd' | wc -l
- 214

上面看到400,是否和table_open_cache有关?经过测试得出:MySQL变量 Open_tables 打开了 table_open_cache的数目,和lsof中的MYI和MYD数目对应(MYISAM)。
即 Open_tables <= table_open_cache,要是Open_tables 和 table_open_cache 一样,表示MySQL已经用完了表缓存,可以适当的调大。
那214是什么意思?是不是INNODB表?经验证确认:

- zjy@localhost : (none) 10:43:54>select count(*) from information_schema.tables where ENGINE='innodb';
- +----------+
- | count(*) |
- +----------+
- | 214 |
- +----------+
- 1 row in set (0.05 sec)

从上面的信息中得出:
- open_files_limit = table_open_cache*2 + innodb表
把上面的数字带进去:
- open_files_limit = 400*2 + 214 = 1014
结果为1014 要小于默认的1024,为什么默认时候1024报错呢,那除这些外还包含什么?
- root@localhost:/proc/27732/fd# ls -lh | grep -v MYI | grep -v MYD | grep -v "\.ibd" | wc -l
- 23
- #注意这个出现的数目不是固定的,有随机性。包含了各种日志、共享表空间、socket文件等信息。
最后结果:
- open_files = 400*2 + 214 + 23(随机) = 1037
得到了最后的打开文件描述符的结果为1037,那把 open_files_limit 设置成1037看看会是什么情况?理论上不能创建表了,重启之后但是数据库正常,那创建一张INNODB表试试?
可以创建4张表,(和上面说的随机性有关系,因为此时的数据不是23了。)到创建第5张表的时候:
- zjy@localhost : zhoujy 11:03:24>create table idx_mer5(id int,name varchar(10),name1 varchar(10),address varchar(30))engine =innodb;
- ERROR 23 (HY000): Out of resources when opening file './zhoujy/' (Errcode: 24)
数据库直接报错,无法创建表,此时重启数据库,又会出现和本文开头的错误信息,因为此时会多了(ls -lh | grep -v MYI | grep -v MYD | grep -v CSV | grep -v "\.ibd")的内容。找到问题出现的原因了。解决办法是:
1,在不修改open_files_limit下把table_open_cache参数调小。
2,修改open_files_limit,至少设置成上面的这个公式。
总结:
在Mysql数据库中,想知道Mysql打开了多少张表,用:

- root@localhost >show global status like 'open%';
- +--------------------------+-------+
- | Variable_name | Value |
- +--------------------------+-------+
- | Open_files | 351 |
- | Open_streams | 0 |
- | Open_table_definitions | 305 |
- | Open_tables | 305 |
- | Opened_files | 996 |
- | Opened_table_definitions | 403 |
- | Opened_tables | 1227 |
- +--------------------------+-------+
- 7 rows in set (0.00 sec)
- 具体打开了哪些表:
root@localhost >show open tables;

打开了多少文件描述符,用:

- root@zhoujy:~# pidof mysqld
- 19068
- root@zhoujy:~# cd /proc/19068/fd
- #总的文件描述符:
- root@zhoujy:/proc/19068/fd# ls -lh | wc -l
- 498
- #MyISAM描述符:
- root@zhoujy:/proc/19068/fd# ls -lh | grep 'MYD' | wc -l
- 172
- #CSV描述符:
- root@zhoujy:/proc/19068/fd# ls -lh | grep 'CSV' | wc -l
- 2
- #Innodb描述符:
- root@zhoujy:/proc/19068/fd# ls -lh | grep '\.ibd' | wc -l
- 131
- 要是此时的【文件描述符】的总数 和 open_files_limit 一样,在新建表的时候就会导致数据库报打不开表的错误信息。

知识点:
MyISAM和CSV表打开时占用2个文件描述符,Innodb则需要1个文件描述符。一些日志信息(relay log,binlog,error-log等)也需要文件描述符。table_open_cache对MyISAM有效,对Innodb无效。当运行 flush tables 关闭表的时候,只对MyISAM表有效,即关闭有MISAM表的文件描述符,Innodb表也会关闭,但是文件描述符不会关。
当表都是MyISAM,在极端的情况下,table_open_cache数目的表全部被打开(512张)就会占用掉1024个文件描述符。而open_files_limit是1024的话,就会出现报错的情况(本文例子的情况)。所以如果是有大量的 MyISAM 表,那么就需要特别注意打开文件数是否会超出限制了。
总之,确实设置open_files_limit的时候,先要知道table_open_cache 为多少,再加上inodb表的数目和一些日志的数目。上面的结果和系统的ulimit没有关系(ubuntu默认apt下来的实例),要是不是默认安装的实例呢?请继续看:
在测试中发现,设置OS的文件描述符(/etc/security/limits.conf)值是无效的,即MySQL启动后open_files_limit始终以my.cnf中设置的参数open_files_limit为准。(版本MySQL5.5.29 ubuntu0.12.04.1),而在非Ubuntu中是按照他们(os和mysql)哪个最高用哪个的方法,通过 cat /proc/10415/limits 查看,依然都是数据库配置文件(open_files_limit)中设置的值。怀疑是ubuntu定制mysql的问题(apt下来的mysql)。
而用mysqld_safe开启的实例(非apt-get install 安装),则按照下面的规则:

- 默认设置的open_files_limit 比其他相关的参数都大。[max_connections*5和10+max_connections+table_cache_size*2 大]
- 一:
- 1:ulimit -n 65535
- 2:修改 my.cnf 限制
- open_files_limit = 10000
- 3:重启 mysql
- 4:show global variables like '%open%';
- | open_files_limit | 10000 |
- 二:
- 注释 open_files_limit
- | open_files_limit | 65535
- 三:
- 1:ulimit -n 5000
- 2:修改 my.cnf 限制
- open_files_limit = 10000
- 3:重启 mysql
- 4:show global variables like '%open%';
- | open_files_limit | 10000
- 四:
- 注释 open_files_limit
- | open_files_limit | 5000
- 这里总结一句话:当open_files_limit没有被配置的时候,比较max_connections*5和ulimit -n的值,哪个大用哪个,当open_file_limit被配置的时候,
比较open_files_limit和max_connections*5的值,哪个大用哪个。

注意:open_files_limit 大小和 max_connections*5需要比较,那个最大就用那个值来设置open_files_limit 。【比较open_files_limit,max_connections*5和10+max_connections+table_cache_size*2中最大值】

- --my.cnf--
- open_files_limit = 5000
- max_connections = 1024
- mysql> show global variables like '%open%';
- +-------------------+----------+
- | Variable_name | Value |
- +-------------------+----------+
- | open_files_limit | 5120 | #1024*5 > 5000
- +-------------------+----------+

- vi /etc/security/limits.conf
- mysql soft nofile 65536
- mysql hard nofile 65536
总结:
所以在配置open_files_limit的时候,设置多大合适,需要知道具体的表数目和类型等,具体情况需要自己分析。没有配置的则需要注意配置OS的ulimit(启动前设置)和max_connections的大小。而用apt-get 下来的mysql实例则都是按照open_files_limit和max_connections 来比较设置的,和OS的ulimit无关。
(转)MySQL open_files_limit相关设置的更多相关文章
- MySQL open_files_limit相关设置
背景: 数据库链接不上,报错: root@localhost:/var/log/mysql# mysql -uzjy -p -h192.168.1.111 --default-charact ...
- MySQL的相关设置
1.启动MySQL服务:# service mysqld start 2.为MySQL设置root用户密码:# mysql -u root mysql>set password for roo ...
- 关于MYSQL数据库安装方式及相关设置简要说明
网上关于MYSQL的教程非常多,但都不是最新的,我这里只是针对最新版本的MY SQL 的安装与设置进行一个简要的说明,大部份操作都相同. 以下是按照WINDOWS 64位操作系统+MY SQL 5.6 ...
- RDS MySQL 全文检索相关问题的处理
RDS MySQL 全文检索相关问题 1. RDS MySQL 对全文检索的支持 2. RDS MySQL 全文检索相关参数 3. RDS MySQL 全文检索中文支持 3.1 MyISAM 引擎表 ...
- MySQL复制相关参数详解
MySQL复制相关参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.复制相关系统变量 1>.server_id 是必须设置在master和每个slave上的唯一标 ...
- linux安装卸载MySQL以及密码设置+Hive测试
linux系统卸载MYSQL 1,先通过yum方式卸载mysql及相关组件 命令:yum remove mysql* 2.通过命令:rpm -qa|grep -i mysql 查找系统的有关于mysq ...
- 详解慢查询日志的相关设置及mysqldumpslow工具
概述 mysql慢查询日志是mysql提供的一种日志记录,它是用来记录在mysql中相应时间超过阈值的语句,就是指运行时间超过long_query_time值的sql,会被记录在慢查询日志中.long ...
- mysql数据库相关流程图/原理图
mysql数据库相关流程图/原理图 1.mysql主从复制原理图 mysql主从复制原理是大厂后端的高频面试题,了解mysql主从复制原理非常有必要. 主从复制原理,简言之,就三步曲,如下: 主数据库 ...
- mysql开发相关
1.mysql事务原理,特性,事务并发控制2.如何解决高并发场景下的插入重复3.乐观锁和悲观锁4.常用数据库引擎之间区别5.mysql索引6.B-Tree7.mysql索引类型8.什么时候创建索引9. ...
随机推荐
- ZooKeeper-3.4.10分布式安装指南
目录 目录 1 1. 前言 1 2. 约定 1 3. 安装步骤 2 3.1. 配置/etc/hosts 2 3.2. 设置myid 2 3.3. 修改conf/zoo.cfg 2 3.4. 修改/bi ...
- (转)在ASP.NET MVC3 中利用Jsonp跨域访问
原文地址:http://www.cnblogs.com/skm-blog/p/3431999.html 在信息系统开发的时,根据相关业务逻辑难免会多系统之间互相登录.一般情况下我们需要在多系统之间使用 ...
- no getter for property named 'power_state
错误信息:nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for pr ...
- mybatis 基础教程
1.引用mybatis.jar包,以后依赖包. 2.配置映射文件(一个是主配置文件,一个是sql映射文件),注意,mapper.xml 文件必须和dao放在一起. 3.mybatis.xml文件说明 ...
- BOLT.NET 学习笔记(一) 开篇 用.net winform 快速开发 炫酷的界面
BOLT.NET 学习笔记(一) 开篇 用.net winform 快速开发 炫酷的界面 bolt 基本介绍 Bolt界面引擎是迅雷公司从2009年开始开发的第四代界面库.迅雷7是首个采用该引擎成功开 ...
- putty连接fedora
putty提示“Connection refused” 但可以ping通 经查,解决方法如下: 首先判断是否安装ssh rpm -qa openssh rpm -qa openssh-server 之 ...
- Fiddler2抓包
https://www.cnblogs.com/conquerorren/p/8472054.html https://www.cnblogs.com/conquerorren/p/8472218.h ...
- Slq怎么样获取首条记录和最后一条记录
sql如何查询表的第一条记录和最后一条记录 方法一:使用top select TOP 1 * from apple;TOP 1 表示表apple中的第一条数据 select TOP 1 * from ...
- ie8在win7系统下怎么安装或重装?[转载]
(一)对于已卸载了IE8的用户 因为微软并没有提供用于Windows 7系统的IE8独立安装包,Windows 7用户是无法通过下载安装包的方法来重装IE8的,而是默认将IE8的安装程序集成在Wind ...
- [ActionScript 3.0] AS3 ServerSocket示例(官方示例)
下面的示例创建一个套接字服务器.要使用该服务器,可将套接字绑定到本地端口,然后从其他应用程序连接到该端口.该服务器仅识别 UTF-8 字符串. package { import flash.displ ...