社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

MySQL的open_file_limit配置迷雾

老叶茶馆 • 4 年前 • 330 次点击  
导读
作者:魏新平,知数堂第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配置文件如

  1. [mysqld]

  2. user = mysql

  3. port = 5721

  4. socket = /tmp/mysql_sandbox5721.sock

  5. basedir = /root/opt/mysql/5.7.21

  6. datadir = /opt/ msb_5_7_21/data

  7. tmpdir = /opt/msb_5_7_21/tmp

  8. pid-file = /opt/msb_5_7_21/data/mysql_sandbox5721.pid

  9. bind-address = 127.0.0.1

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

结果如下

  1. [root@mysqlmaster ~]# ps -ef | grep mysqld

  2. 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

  3. 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

  4. root 10583 5177 0 09:57 pts/4 00:00:00 grep --color=auto mysqld

  5. [root@mysqlmaster ~]# cat /proc/3253/limits |grep files

  6. Max open files 5000 5000 files

  7. --------------------------------------------------------------------------------

  8. mysql [localhost:5721] {root } ((none)) > SELECT @@open_files_limit ;

  9. +--------------------+

  10. | @@open_files_limit |

  11. +--------------------+

  12. | 5000 |

  13. +--------------------+

  14. 1 row in set (0.00 sec)

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

4) 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

结果为

  1. [root@mysqlmaster msb_5_7_21]# ps -ef | grep mysqld

  2. 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

  3. 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

  4. root 80555 1129 0 10:43 pts/2 00:00:00 grep --color=auto mysqld

  5. [root@mysqlmaster msb_5_7_21]#

  6. [root@mysqlmaster msb_5_7_21]# cat /proc/80227/limits |grep files

  7. Max open files 6162 6162 files

  8. ------------------------------------------------------------------------------------------------

  9. mysql [localhost:5721] {root} ((none)) > SELECT @@open_files_limit ;

  10. +--------------------+

  11. | @@open_files_limit |

  12. +--------------------+

  13. | 6162 |

  14. +--------------------+

  15. 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

结果如下

  1. [root@mysqlmaster msb_5_7_21]# ps -ef | grep mysqld

  2. 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

  3. 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

  4. root 88300 1129 0 10:48 pts/2 00:00:00 grep --color=auto mysqld

  5. [root@mysqlmaster msb_5_7_21]# cat /proc/88132/limits | grep files

  6. Max open files 10005 10005 files

  7. ----------------------------------------------------------------------------------------------

  8. mysql [localhost:5721] {root} ((none)) > SELECT @@open_files_limit ;

  9. +--------------------+

  10. | @@open_files_limit |

  11. +--------------------+

  12. | 10005 |

  13. +--------------------+

  14. 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

结果如下:

  1. [root@mysqlmaster msb_5_7_21]# ps -ef | grep mysql

  2. 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

  3. 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

  4. root 94254 1129 0 10:52 pts/2 00:00:00 grep --color =auto mysql

  5. [root@mysqlmaster msb_5_7_21]# cat /proc/94031/limits | grep files

  6. Max open files 6000 6000 files

  7. ---------------------------------------------------------------------------------------

  8. mysql [localhost:5721] {root} ((none)) > SELECT @@open_files_limit ;

  9. +--------------------+

  10. | @@open_files_limit |

  11. +--------------------+

  12. | 6000 |

  13. +--------------------+

  14. 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

结果如下:

  1. [root@mysqlmaster msb_5_7_21 ]# ps -ef | grep mysqld

  2. 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

  3. 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

  4. root 104460 1129 0 10:58 pts/2 00:00:00 grep --color=auto mysqld

  5. [root@mysqlmaster msb_5_7_21]# cat /proc/104269/limits | grep files

  6. Max open files 4200 4200 files

  7. ------------------------------------------------------------------

  8. mysql [localhost:5721] {root} ((none)) > SELECT @@open_files_limit ;

  9. +--------------------+

  10. | @@open_files_limit |

  11. +--------------------+

  12. | 4200 |

  13. +--------------------+

  14. 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用户启动的时候,才会受到这个限制。





扫码加入MySQL技术Q群

(群号:650149401)

   



点“在看”给我一朵小黄花



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50258
 
330 次点击