MySQL怎么计算打开文件数
答案:2 悬赏:40 手机版
解决时间 2021-02-19 08:43
- 提问者网友:孤凫
- 2021-02-18 11:04
MySQL怎么计算打开文件数
最佳答案
- 五星知识达人网友:执傲
- 2021-02-18 11:58
看看打开了几个文件lsof | grep /home/mysql
...
mysqld 24349 mysql 5u unix 0x000001041e8de040 4244009 /home/mysql/mysql.sock
mysqld 24349 mysql 6u REG 8,33 2048 30425188 /home/mysql/mysql/host.MYI
mysqld 24349 mysql 7u REG 8,33 0 30425189 /home/mysql/mysql/host.MYD
mysqld 24349 mysql 8u REG 8,33 2048 30425153 /home/mysql/mysql/user.MYI
mysqld 24349 mysql 9u REG 8,33 892 30425155 /home/mysql/mysql/user.MYD
mysqld 24349 mysql 10u REG 8,33 5120 30425126 /home/mysql/mysql/db.MYI
mysqld 24349 mysql 11u REG 8,33 3080 30425148 /home/mysql/mysql/db.MYD
mysqld 24349 mysql 12u REG 8,33 4096 30425154 /home/mysql/mysql/tables_priv.MYI
mysqld 24349 mysql 13u REG 8,33 0 30425157 /home/mysql/mysql/tables_priv.MYD
mysqld 24349 mysql 14u REG 8,33 4096 30425143 /home/mysql/mysql/columns_priv.MYI
mysqld 24349 mysql 15u REG 8,33 0 30425156 /home/mysql/mysql/columns_priv.MYD
mysqld 24349 mysql 16u REG 8,33 4096 30425127 /home/mysql/mysql/procs_priv.MYI
mysqld 24349 mysql 17u REG 8,33 0 30425136 /home/mysql/mysql/procs_priv.MYD
mysqld 24349 mysql 18u REG 8,33 1024 30425173 /home/mysql/mysql/servers.MYI
mysqld 24349 mysql 19u REG 8,33 0 30425174 /home/mysql/mysql/servers.MYD
mysqld 24349 mysql 20u REG 8,33 2048 30425182 /home/mysql/mysql/event.MYI
mysqld 24349 mysql 21u REG 8,33 0 30425183 /home/mysql/mysql/event.MYD
...
可以看到,总共打开了8个表,每个表分别有2个文件描述符,看来没错。
3. 再来看 status 结果
mysql>show global status like 'open_%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Open_files | 17 |
| Open_streams | 0 |
| Open_table_definitions | 15 |
| Open_tables | 8 |
| Opened_files | 52 |
| Opened_tables | 15 |
+------------------------+-------+
4. flush tables 后再看看
mysql>flush tables;
mysql> show global status like 'open_%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Open_files | 1 |
| Open_streams | 0 |
| Open_table_definitions | 0 |
| Open_tables | 0 |
| Opened_files | 52 |
| Opened_tables | 15 |
mysql> show global status like 'open_%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Open_files | 1 |
| Open_streams | 0 |
| Open_table_definitions | 0 |
| Open_tables | 0 |
| Opened_files | 52 |
| Opened_tables | 15 |
+------------------------+-------+lsof | grep /home/mysql
...
mysqld 24349 mysql 5u unix 0x000001041e8de040 4244009 /home/mysql/mysql.sock
mysqld 24349 mysql 22u unix 0x00000102378ff980 4244128 /home/mysql/mysql.sock
...
可以看到,flush 之后,所有的文件描述符都释放了。
通过测试可以得知,另一个打开的文件描述符是 slow query log所用。
如果是有大量的 MyISAM 表,那么就需要特别注意打开文件数是否会超出限制了。
二、原理
接下来仔细了解下这个最大文件数相关的参数:
table_cache (新版本改成了 table_open_cache) The number of cached open tables.
open_files_limit If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit().
If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger)
number of files.
如果 open_files_limit 不是设置为 0,则以 setrlimit() 函数计算后的结果为准,如果设置为 0,则实际值是 max_connections*5 或 max_connections + table_cache*2 中的最大者。
因此,想要解决打开文件数超限的问题,还需要综合系统内核限制(ulimit -n),mysqld自身限制(open_files_limit),以及表缓存数(table_open_cache)等多方面因素。
不过,实际测试中,发现却不是这样的,open_files_limit采用了内核的最大限制,而非上面的计算结果。
. 查看内核限制
ulimit -n
65535
2. 修改 my.cnf 限制
vi /etc/my.cnf
...
open_files_limit = 10000
...
3. 重启 mysqld
/etc/init.d/mysql restart
4. 查看结果
mysql>show global variables like '%open%';
| open_files_limit | 65535 |
| table_open_cache | 1000 |
5. 不设置 open_files_limit 看看
vi /etc/my.cnf
...
#open_files_limit = 10000
...
重启
/etc/init.d/mysql restart
查看
mysql>show global variables like '%open%';
| open_files_limit | 65535 |
| table_open_cache | 1000 |
而这个时候,按计算公式结果如下:
| max_connections | 100 |
| table_open_cache | 1000 |
来计算一下:
max_open_files_1 = max_connections + table_cache * 2 = 100 + 1000 * 2 = 2100
max_open_files_2 = max_connections*5 = 100 * 5 = 500
6. 修改 ulimit 试试看:
unlimit -n 5000
vi /etc/my.cnf
...
open_files_limit = 10000
...
/etc/init.d/mysql restart
mysql>show global variables like '%open%';
| open_files_limit | 10000 |
| table_open_cache | 1000 |
open_files_limit 比内核最大限制数还大,因此以 open_files_limit 为准。
vi /etc/my.cnf
...
#open_files_limit = 10000
...
/etc/init.d/mysql restart
mysql>show global variables like '%open%';
| open_files_limit | 5000 |
| table_open_cache | 1000 |
看到了,变成了新的内核最大限制
看到了吧,结果完全跟文档描述的以及mysql源码中写的不一样,看来预编译版本有些地方不太可靠啊 :(
以上测试在mysql 5.1.23-rc(预编译), mysql-5.1.24-rc(自编译) 以及 5.0.45(预编译) 均一样。
uname -a
Linux s1.yejr.com 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux
mysql> select version();
+---------------+
| version() |
+---------------+
| 5.1.23-rc-log |
+---------------+
================= 222222222222=========
mysql Lost Connection During Query 问题解决方法2008-07-25 14:45这是在使用 mysql 的过程中,困扰我很久的一个问题,今天终于找到根本原因,得以彻底解决,真是可喜可贺啊!下面详细地总结一下:问题描述:在使用 mysql 的过程中发现,偶尔的查询或一段时间内的登录会失败,返回的错误提示信息为:Lost Connection During Query。问题定位:这个问题在半年、甚至一年前都遇到过,由于它不是必现,往往你去看的时候没法重现,并且一个 mysql server 管理好多个数据库,查询又不是时刻发生的,常常不知所措。无法登录时,更是束手无策。最初,比较粗暴的方法是重启 mysql,问题在一段时间内能缓解。后来,使用 flush tables 也能在一段时间内缓解。再后来,通过查看 mysql 的错误日志,发现一共有三种提示信息:第一种:080724 19:55:05 [ERROR] Error in accept: Too many open files,这种明显是由于 mysql 打开文件个数过多,mysql 无法再“接收”新的连接进来,也就是没有办法登录,造成连接失败。第二种:080724 19:45:11 [ERROR] /usr/local/mysql/bin/mysqld: Sort aborted,这种是放弃了排序,但没有说明原因。第三种:080725 9:30:33 [ERROR] /usr/local/mysql/bin/mysqld: Can't open file: 'OperateRecord.MRG' (errno: 24),这种是打开文件失败,错误码是24,通过 perror 查询详细的错误原因是:OS error code 24: Too many open files,也是打开文件过多。再通过 status 查看 mysql 的打开文件个数,此时一般都接近 1000 个。再通过 show variables 查看 mysql 的配置,默认其打开文件个数为 open_files_limit 为 2048,按道理说这个大小是足够的。问题解决:原来 mysql 中的 open_files_limit 只是限制 mysql 这个进程打开的最大文件个数。而内核也会对 mysql 打开的进程数进行限制,并且优先级要高。通过 ulimit -a 查看 mysql 这个用户的最大打开文件个数,发现其值为 1024(linux 默认都是1024)。原来,mysql 已经打开了近 1000 个表,若再打开一个 merge 表(包含100个子表),导致文件句柄过多而失败。通过修改 /etc/security/limits.conf 配置文件,添加如下行:* - nofile 4096,把该限制放大,重新启动 mysql ,问题得到彻底解决。设置 mysql 打开文件限制方法:把 set-variable=open_files_limit=10240 加到配置文件中。
...
mysqld 24349 mysql 5u unix 0x000001041e8de040 4244009 /home/mysql/mysql.sock
mysqld 24349 mysql 6u REG 8,33 2048 30425188 /home/mysql/mysql/host.MYI
mysqld 24349 mysql 7u REG 8,33 0 30425189 /home/mysql/mysql/host.MYD
mysqld 24349 mysql 8u REG 8,33 2048 30425153 /home/mysql/mysql/user.MYI
mysqld 24349 mysql 9u REG 8,33 892 30425155 /home/mysql/mysql/user.MYD
mysqld 24349 mysql 10u REG 8,33 5120 30425126 /home/mysql/mysql/db.MYI
mysqld 24349 mysql 11u REG 8,33 3080 30425148 /home/mysql/mysql/db.MYD
mysqld 24349 mysql 12u REG 8,33 4096 30425154 /home/mysql/mysql/tables_priv.MYI
mysqld 24349 mysql 13u REG 8,33 0 30425157 /home/mysql/mysql/tables_priv.MYD
mysqld 24349 mysql 14u REG 8,33 4096 30425143 /home/mysql/mysql/columns_priv.MYI
mysqld 24349 mysql 15u REG 8,33 0 30425156 /home/mysql/mysql/columns_priv.MYD
mysqld 24349 mysql 16u REG 8,33 4096 30425127 /home/mysql/mysql/procs_priv.MYI
mysqld 24349 mysql 17u REG 8,33 0 30425136 /home/mysql/mysql/procs_priv.MYD
mysqld 24349 mysql 18u REG 8,33 1024 30425173 /home/mysql/mysql/servers.MYI
mysqld 24349 mysql 19u REG 8,33 0 30425174 /home/mysql/mysql/servers.MYD
mysqld 24349 mysql 20u REG 8,33 2048 30425182 /home/mysql/mysql/event.MYI
mysqld 24349 mysql 21u REG 8,33 0 30425183 /home/mysql/mysql/event.MYD
...
可以看到,总共打开了8个表,每个表分别有2个文件描述符,看来没错。
3. 再来看 status 结果
mysql>show global status like 'open_%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Open_files | 17 |
| Open_streams | 0 |
| Open_table_definitions | 15 |
| Open_tables | 8 |
| Opened_files | 52 |
| Opened_tables | 15 |
+------------------------+-------+
4. flush tables 后再看看
mysql>flush tables;
mysql> show global status like 'open_%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Open_files | 1 |
| Open_streams | 0 |
| Open_table_definitions | 0 |
| Open_tables | 0 |
| Opened_files | 52 |
| Opened_tables | 15 |
mysql> show global status like 'open_%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Open_files | 1 |
| Open_streams | 0 |
| Open_table_definitions | 0 |
| Open_tables | 0 |
| Opened_files | 52 |
| Opened_tables | 15 |
+------------------------+-------+lsof | grep /home/mysql
...
mysqld 24349 mysql 5u unix 0x000001041e8de040 4244009 /home/mysql/mysql.sock
mysqld 24349 mysql 22u unix 0x00000102378ff980 4244128 /home/mysql/mysql.sock
...
可以看到,flush 之后,所有的文件描述符都释放了。
通过测试可以得知,另一个打开的文件描述符是 slow query log所用。
如果是有大量的 MyISAM 表,那么就需要特别注意打开文件数是否会超出限制了。
二、原理
接下来仔细了解下这个最大文件数相关的参数:
table_cache (新版本改成了 table_open_cache) The number of cached open tables.
open_files_limit If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit().
If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger)
number of files.
如果 open_files_limit 不是设置为 0,则以 setrlimit() 函数计算后的结果为准,如果设置为 0,则实际值是 max_connections*5 或 max_connections + table_cache*2 中的最大者。
因此,想要解决打开文件数超限的问题,还需要综合系统内核限制(ulimit -n),mysqld自身限制(open_files_limit),以及表缓存数(table_open_cache)等多方面因素。
不过,实际测试中,发现却不是这样的,open_files_limit采用了内核的最大限制,而非上面的计算结果。
. 查看内核限制
ulimit -n
65535
2. 修改 my.cnf 限制
vi /etc/my.cnf
...
open_files_limit = 10000
...
3. 重启 mysqld
/etc/init.d/mysql restart
4. 查看结果
mysql>show global variables like '%open%';
| open_files_limit | 65535 |
| table_open_cache | 1000 |
5. 不设置 open_files_limit 看看
vi /etc/my.cnf
...
#open_files_limit = 10000
...
重启
/etc/init.d/mysql restart
查看
mysql>show global variables like '%open%';
| open_files_limit | 65535 |
| table_open_cache | 1000 |
而这个时候,按计算公式结果如下:
| max_connections | 100 |
| table_open_cache | 1000 |
来计算一下:
max_open_files_1 = max_connections + table_cache * 2 = 100 + 1000 * 2 = 2100
max_open_files_2 = max_connections*5 = 100 * 5 = 500
6. 修改 ulimit 试试看:
unlimit -n 5000
vi /etc/my.cnf
...
open_files_limit = 10000
...
/etc/init.d/mysql restart
mysql>show global variables like '%open%';
| open_files_limit | 10000 |
| table_open_cache | 1000 |
open_files_limit 比内核最大限制数还大,因此以 open_files_limit 为准。
vi /etc/my.cnf
...
#open_files_limit = 10000
...
/etc/init.d/mysql restart
mysql>show global variables like '%open%';
| open_files_limit | 5000 |
| table_open_cache | 1000 |
看到了,变成了新的内核最大限制
看到了吧,结果完全跟文档描述的以及mysql源码中写的不一样,看来预编译版本有些地方不太可靠啊 :(
以上测试在mysql 5.1.23-rc(预编译), mysql-5.1.24-rc(自编译) 以及 5.0.45(预编译) 均一样。
uname -a
Linux s1.yejr.com 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux
mysql> select version();
+---------------+
| version() |
+---------------+
| 5.1.23-rc-log |
+---------------+
================= 222222222222=========
mysql Lost Connection During Query 问题解决方法2008-07-25 14:45这是在使用 mysql 的过程中,困扰我很久的一个问题,今天终于找到根本原因,得以彻底解决,真是可喜可贺啊!下面详细地总结一下:问题描述:在使用 mysql 的过程中发现,偶尔的查询或一段时间内的登录会失败,返回的错误提示信息为:Lost Connection During Query。问题定位:这个问题在半年、甚至一年前都遇到过,由于它不是必现,往往你去看的时候没法重现,并且一个 mysql server 管理好多个数据库,查询又不是时刻发生的,常常不知所措。无法登录时,更是束手无策。最初,比较粗暴的方法是重启 mysql,问题在一段时间内能缓解。后来,使用 flush tables 也能在一段时间内缓解。再后来,通过查看 mysql 的错误日志,发现一共有三种提示信息:第一种:080724 19:55:05 [ERROR] Error in accept: Too many open files,这种明显是由于 mysql 打开文件个数过多,mysql 无法再“接收”新的连接进来,也就是没有办法登录,造成连接失败。第二种:080724 19:45:11 [ERROR] /usr/local/mysql/bin/mysqld: Sort aborted,这种是放弃了排序,但没有说明原因。第三种:080725 9:30:33 [ERROR] /usr/local/mysql/bin/mysqld: Can't open file: 'OperateRecord.MRG' (errno: 24),这种是打开文件失败,错误码是24,通过 perror 查询详细的错误原因是:OS error code 24: Too many open files,也是打开文件过多。再通过 status 查看 mysql 的打开文件个数,此时一般都接近 1000 个。再通过 show variables 查看 mysql 的配置,默认其打开文件个数为 open_files_limit 为 2048,按道理说这个大小是足够的。问题解决:原来 mysql 中的 open_files_limit 只是限制 mysql 这个进程打开的最大文件个数。而内核也会对 mysql 打开的进程数进行限制,并且优先级要高。通过 ulimit -a 查看 mysql 这个用户的最大打开文件个数,发现其值为 1024(linux 默认都是1024)。原来,mysql 已经打开了近 1000 个表,若再打开一个 merge 表(包含100个子表),导致文件句柄过多而失败。通过修改 /etc/security/limits.conf 配置文件,添加如下行:* - nofile 4096,把该限制放大,重新启动 mysql ,问题得到彻底解决。设置 mysql 打开文件限制方法:把 set-variable=open_files_limit=10240 加到配置文件中。
全部回答
- 1楼网友:摆渡翁
- 2021-02-18 12:28
因此,想要解决打开文件数超限的问题,还需要综合系统内核限制(ulimit -n),mysqld自身限制(open_files_limit),以及表缓存数(table_open_cache)等多方面因素。 不过,实际测试中,发现却不是这样的,open_files_limit采用了内核的最大限制,而非上面的计算结果。 1. 查看内核限制 ulimit -n 65535 2. 修改 my.cnf 限制 vi /etc/my.cnf
open_files_limit = 10000
... 3. 重启 mysqld /etc/init.d/mysql restart 4. 查看结果 mysql>show global variables like '%open%';
| open_files_limit | 65535 |
| table_open_cache | 1000 | 5. 不设置 open_files_limit 看看 vi /etc/my.cnf
#open_files_limit = 10000
重启/etc/init.d/mysql restart查看mysql>show global variables like '%open%';
| open_files_limit | 65535 |
| table_open_cache | 1000 | 而这个时候,按计算公式结果如下: | max_connections | 100 | | table_open_cache | 1000 | 来计算一下: max_open_files_1 = max_connections + table_cache * 2 = 100 + 1000 * 2 = 2100 max_open_files_2 = max_connections*5 = 100 * 5 = 500 6. 修改 ulimit 试试看: unlimit -n 5000
vi /etc/my.cnf
open_files_limit = 10000
/etc/init.d/mysql restart
mysql>show global variables like '%open%';
| open_files_limit | 10000 |
| table_open_cache | 1000 | open_files_limit 比内核最大限制数还大,因此以 open_files_limit 为准。 vi /etc/my.cnf
#open_files_limit = 10000
/etc/init.d/mysql restart
mysql>show global variables like '%open%';
| open_files_limit | 5000 |
| table_open_cache | 1000 | 看到了,变成了新的内核最大限制 看到了吧,结果完全跟文档描述的以及mysql源码中写的不一样,看来预编译版本有些地方不太可靠啊 :( 以上测试在mysql 5.1.23-rc(预编译), mysql-5.1.24-rc(自编译) 以及 5.0.45(预编译) 均一样。 uname -a
linux s1.yejr.com 2.6.9-55.elsmp #1 smp fri apr 20 16:36:54 edt 2007 x86_64 x86_64 x86_64 gnu/linux
mysql> select version();
+---------------+
| version() |+---------------+
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯