MySQL的open_file_limit配置迷雾

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

导读

作者:魏新平,知数堂第5期MySQL实战班学员,第10期MySQL优化班学员,现任职助教。

一、官方解释

mysqld进程能使用的最大文件描述符数量,mysql实际的取值会从下面四个值当中获取最大的。

  1. 10 + maxconnections + (tableopen_cache * 2)

  2. max_connections * 5

  3. operating system limit if positive

  4. if operating system limit is Infinity:

open_files_limit value specified at startup, 5000 if none

我们接下来测试让mysql分别取上面四种值为实际的取值。

二、测试mysql版本和系统版本

操作系统版本为CentOS Linux release 7.4.1708 (Core),全新安装,没有任何配置。

mysql版本 Percona-Server-5.7.21-20-Linux.x86_64

接下来开始测试了。

没有配置open_files_limit参数(root用户登陆操作)

mysql配置文件如

[mysqld]
user = mysql
port =  5721
socket =  /tmp/mysql_sandbox5721.sock
basedir =  /root/opt/mysql/5.7.21
datadir =  /opt/msb_5_7_21/data
tmpdir =  /opt/msb_5_7_21/tmp
pid-file =  /opt/msb_5_7_21/data/mysql_sandbox5721.pid
bind-address =  127.0.0.1

table_open_cache默认值是2000,max_connections默认值是151+1,因为还有一个extra_max_connections,ulimit -n 的值为1024。

结果如下

[root@mysqlmaster ~]# ps -ef | grep mysqld
root 3047  1  0  09:52 pts/2  00:00:00  /bin/sh bin/mysqld_safe --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf
mysql 3253  3047  0  09:52 pts/2  00:00:02  /root/opt/mysql/5.7.21/bin/mysqld --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf --basedir=/root/opt/mysql/5.7.21  --datadir=/opt/msb_5_7_21/data --plugin-dir=/root/opt/mysql/5.7.21/lib/mysql/plugin --user=mysql --log-error=/opt/msb_5_7_21/data/msandbox.err --pid-file=/opt/msb_5_7_21/data/mysql_sandbox5721.pid --socket=/tmp/mysql_sandbox5721.sock --port=5721
root 10583  5177  0  09:57 pts/4  00:00:00 grep --color=auto mysqld
[root@mysqlmaster ~]# cat /proc/3253/limits |grep files
Max open files 5000  5000 files
--------------------------------------------------------------------------------
mysql [localhost:5721]  {root}  ((none))  > SELECT @@open_files_limit  ;
+--------------------+
|  @@open_files_limit  |
+--------------------+
|  5000  |
+--------------------+
1 row in  set  (0.00 sec)

不管是系统层面还是mysql,取值都是5000,符合了第四种情况

  1. if operating system limit is Infinity:

openfileslimit value specified at startup, 5000 if none

其他几种公式的值为:

1、select @@max_connections + @@extra_max_connections + 10 + @@table_open_cache*2 = 4162

2、select (@@max_connections+@@extra_max_connections)*5 = 760

3、ulimit -n = 1024

那我们接下来依次增大其他几种公式的值,看看结果会有什么变化。

10 + maxconnections + (tableopen_cache * 2)最大

设置table_open_cache=3000,其他不变,取值如下:

1、select @@max_connections + @@extra_max_connections + 10 + @@table_open_cache*2 = 6162

2、select (@@max_connections+@@extra_max_connections)*5 = 760

3、ulimit -n = 1024

4、5000

结果为

[root@mysqlmaster msb_5_7_21]# ps -ef | grep mysqld
root 80009  1  0  10:43 pts/2  00:00:00  /bin/sh bin/mysqld_safe --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf
mysql 80227  80009  11  10:43 pts/2  00:00:01  /root/opt/mysql/5.7.21/bin/mysqld --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf --basedir=/root/opt/mysql/5.7.21  --datadir=/opt/msb_5_7_21/data --plugin-dir=/root/opt/mysql/5.7.21/lib/mysql/plugin --user=mysql --log-error=/opt/msb_5_7_21/data/msandbox.err --pid-file=/opt/msb_5_7_21/data/mysql_sandbox5721.pid --socket=/tmp/mysql_sandbox5721.sock --port=5721
root 80555  1129  0  10:43 pts/2  00:00:00 grep --color=auto mysqld
[root@mysqlmaster msb_5_7_21]#
[root@mysqlmaster msb_5_7_21]# cat /proc/80227/limits |grep files
Max open files 6162  6162 files
------------------------------------------------------------------------------------------------
mysql [localhost:5721]  {root}  ((none))  > SELECT @@open_files_limit  ;
+--------------------+
|  @@open_files_limit  |
+--------------------+
|  6162  |
+--------------------+
1 row in  set  (0.00 sec)
max_connections * 5最大

设置max_connections的值为2000,其他值默认,取值如下:

1、select @@max_connections + @@extra_max_connections + 10 + @@table_open_cache*2 =6011

2、select (@@max_connections+@@extra_max_connections)*5 = 10005

3、ulimit -n = 1024

4、5000

结果如下

[root@mysqlmaster msb_5_7_21]# ps -ef | grep mysqld
root 87914  1  0  10:48 pts/2  00:00:00  /bin/sh bin/mysqld_safe --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf
mysql 88132  87914  21  10:48 pts/2  00:00:01  /root/opt/mysql/5.7.21/bin/mysqld --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf --basedir=/root/opt/mysql/5.7.21  --datadir=/opt/msb_5_7_21/data --plugin-dir=/root/opt/mysql/5.7.21/lib/mysql/plugin --user=mysql --log-error=/opt/msb_5_7_21/data/msandbox.err --pid-file=/opt/msb_5_7_21/data/mysql_sandbox5721.pid --socket=/tmp/mysql_sandbox5721.sock --port=5721
root 88300  1129  0  10:48 pts/2  00:00:00 grep --color=auto mysqld
[root@mysqlmaster msb_5_7_21]# cat /proc/88132/limits | grep files
Max open files 10005  10005 files
----------------------------------------------------------------------------------------------
mysql [localhost:5721]  {root}  ((none))  > SELECT @@open_files_limit  ;
+--------------------+
|  @@open_files_limit  |
+--------------------+
|  10005  |
+--------------------+
1 row in  set  (0.00 sec)
operating system limit if positive最大

我的理解是ulimit -n显示的值。max_connections和table_open_cache取默认值,然后ulimit -n 6000。重启mysql。

公式取值如下:

1、select @@max_connections + @@extra_max_connections + 10 + @@table_open_cache*2 = 4162

2、select (@@max_connections+@@extra_max_connections)*5 = 760

3、ulimit -n = 6000

结果如下:

[root@mysqlmaster msb_5_7_21]# ps -ef | grep mysql
root 93825  1  0  10:52 pts/2  00:00:00  /bin/sh bin/mysqld_safe --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf
mysql 94031  93825  16  10:52 pts/2  00:00:01  /root/opt/mysql/5.7.21/bin/mysqld --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf --basedir=/root/opt/mysql/5.7.21  --datadir=/opt/msb_5_7_21/data --plugin-dir=/root/opt/mysql/5.7.21/lib/mysql/plugin --user=mysql --log-error=/opt/msb_5_7_21/data/msandbox.err --pid-file=/opt/msb_5_7_21/data/mysql_sandbox5721.pid --socket=/tmp/mysql_sandbox5721.sock --port=5721
root 94254  1129  0  10:52 pts/2  00:00:00 grep --color=auto mysql
[root@mysqlmaster msb_5_7_21]# cat /proc/94031/limits | grep files
Max open files 6000  6000 files
---------------------------------------------------------------------------------------
mysql [localhost:5721]  {root}  ((none))  > SELECT @@open_files_limit  ;
+--------------------+
|  @@open_files_limit  |
+--------------------+
|  6000  |
+--------------------+
1 row in  set  (0.00 sec)

三、配置open_files_limit参数(root用户登陆操****作)

配置了open_files_limit参数,还是会取最大值。但是不一样的是第三种公式的取值,也就是ulimit -n不会被考虑进来。而是从另外三种取值当中获取最大的值。

执行ulimit -n 6000 增大限制,然后max_connections,table_open_cache都是默认。open_files_limit设置为4200。重启mysql

结果如下:

[root@mysqlmaster msb_5_7_21]# ps -ef | grep mysqld
root 104048  1  0  10:58 pts/2  00:00:00  /bin/sh bin/mysqld_safe --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf
mysql 104269  104048  19  10:58 pts/2  00:00:01  /root/opt/mysql/5.7.21/bin/mysqld --defaults-file=/opt/msb_5_7_21/my.sandbox.cnf --basedir=/root/opt/mysql/5.7.21  --datadir=/opt/msb_5_7_21/data --plugin-dir=/root/opt/mysql/5.7.21/lib/mysql/plugin --user=mysql --log-error=/opt/msb_5_7_21/data/msandbox.err --open-files-limit=4200  --pid-file=/opt/msb_5_7_21/data/mysql_sandbox5721.pid --socket=/tmp/mysql_sandbox5721.sock --port=5721
root 104460  1129  0  10:58 pts/2  00:00:00 grep --color=auto mysqld
[root@mysqlmaster msb_5_7_21]# cat /proc/104269/limits | grep files
Max open files 4200  4200 files
------------------------------------------------------------------
mysql [localhost:5721]  {root}  ((none))  > SELECT @@open_files_limit  ;
+--------------------+
|  @@open_files_limit  |
+--------------------+
|  4200  |
+--------------------+
1 row in  set  (0.00 sec)

显示的值就变成了4200,明显6000没有被考虑进来,就算是值比4200大。其他的情况和没有配置open_files_limit相同,获取最大的值,篇幅原因就不做赘述了。

四、总结

在没有配置的open_files_limit的情况下,会获取下面公式的最大值。

  1. 10 + maxconnections + (tableopen_cache * 2)

  2. max_connections * 5

  3. operating system limit if positive

  4. if operating system limit is Infinity:

open_files_limit value specified at startup, 5000 if none

在配置了open_files_limit的情况下,第三个值的大小会被忽略。

这里还有一个疑问就是为啥ulimit -n显示1024的时候没有起到限制作用呢。我认为的原因是启动mysqld_safe的用户为root,不受这个值的限制。经过测试不管mysqld的启动用户是什么,只要mysqld_safe启动的用户为root,就不受这个限制。只有在mysqld_safe由非root用户启动的时候,才会受到这个限制。

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看