欢送来到 GreatSQL 社区分享的 MySQL 技术文章,如有疑难或想学习的内容,能够在下方评论区留言,看到后会进行解答
lsof 中附加不同参数产生的后果也不同,小心“踩坑”。
1、背景:
偶尔发现数据库连不上,在数据库的 err 日志中,呈现了“Too many open files”谬误,都晓得这个是 mysqld 过程触发了句柄限度,导致无奈建设新连贯。
度娘下面找到了统计句柄数的命令
lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr| head -n 10
发现输入的后果远超了 ulimit - n 的后果。然而报错景象才继续不长时间,失常状况下不可能产生这么多句柄。
为了钻研这个问题的根因,在本人的服务器下面模仿了以下测试。
服务器配置 4C8G,MySQL 8.0.22,lsof 版本为 4.87(为什么特地介绍 lsof 版本,后续会提到,很重要)
2、测试过程:
1、在服务器下面装置好 MySQL,设置上面的参数,重启数据库服务
max_connections=150
open_files_limit=1000
此时,数据库过程的 open_files_limit 为 2160
mysql> show variables like '%open%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| have_openssl | YES |
| innodb_open_files | 1000 |
| mysqlx_port_open_timeout | 0 |
| open_files_limit | 2160 |
| table_open_cache | 1000 |
| table_open_cache_instances | 16 |
+----------------------------+-------+
6 rows in set (0.01 sec)
其计算公式为 table_open_cache*2+max_connections+10 具体见上面的官网介绍
2、此时数据库刚刚启动,查看过程占用的句柄数
[root@greatdb mysql]# ps -ef| grep mysql
root 6239 8644 0 16:25 pts/5 00:00:00 mysql -uroot
root 10134 8260 0 16:42 pts/1 00:00:00 mysql -uroot
root 10177 1 0 16:47 ? 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql/my.cnf
mysql 11604 10177 8 16:47 ? 00:00:02 /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql/logs/mysqld-error.log --ope
n-files-limit=1000 --pid-file=/data/mysql/mysqld.pid --socket=/data/mysql/mysql.sock --port=3306root 11696 8572 0 16:47 pts/2 00:00:00 grep --color=auto mysql
[root@greatdb mysql]#
[root@greatdb mysql]#
[root@greatdb mysql]# lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr| head -n 10
5727 11604
1575 1384
525 1550
455 879
371 561
135 1101
130 1001
120 16780
114 1304
88 16894
[root@greatdb mysql]#
能够看到刚刚启动的数据库,用下面的命令统计进去的句柄数 5727 就曾经超过了设置的值 2160 了,然而数据库依然能够失常应用和连贯。
2、此时进入数据库,批改最大连贯限度,用于模仿实在超过句柄的状况
set global max_connections=10000
3、在数据库中创立三个分区表,用于疾速占用文件句柄数
create database test;
create table test.tb1(id int, c varchar(10)) partition by hash(id) partitions 1024;
create table test.tb2(id int, c varchar(10)) partition by hash(id) partitions 1024;
create table test.tb3(id int, c varchar(10)) partition by hash(id) partitions 1024;
4、此时再次应用下面的命令查问句柄数
[root@greatdb mysql]# lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr| head -n 10
73485 11604
1575 1384
525 1550
455 879
371 561
135 1101
130 1001
120 16780
114 1304
88 16894
[root@greatdb mysql]#
5、能够看到 mysql 的过程“占用”句柄数曾经达到 73485,远远超过了理论容许的值了,开始狐疑这个统计值不对。
6、应用另外的命令 lsof -p 11604 |wc -l; ls /proc/11604/fd |wc -l 来统计句柄和关上文件,发现比拟失常,在正当范畴内
[root@greatdb mysql]# lsof -p 11604 |wc -l; ls /proc/11604/fd |wc -l
1066
1021
[root@greatdb mysql]#
7、最终比照 lsof -n | head 和 lsof -p 11604 |head 发现了差别,lsof -n 的后果多了一列 TID,察看后发现是线程编号,其值和 performance_schema.threads 中的 thread_id 可能对应上
[root@greatdb mysql]# lsof -p 11604 | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 11604 mysql cwd DIR 253,1 4096 1310723 /data/mysql/data
mysqld 11604 mysql rtd DIR 253,1 4096 2 /
mysqld 11604 mysql txt REG 253,1 441771255 927033 /usr/local/mysql/bin/mysqld
mysqld 11604 mysql DEL REG 0,11 6526074 /[aio]
mysqld 11604 mysql DEL REG 0,11 6526073 /[aio]
mysqld 11604 mysql DEL REG 0,11 6526072 /[aio]
mysqld 11604 mysql DEL REG 0,11 6526071 /[aio]
mysqld 11604 mysql DEL REG 0,11 6526070 /[aio]
mysqld 11604 mysql DEL REG 0,11 6526069 /[aio]
[root@greatdb mysql]#
[root@greatdb mysql]#
[root@greatdb mysql]# lsof -n | head
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,1 4096 2 /
systemd 1 root rtd DIR 253,1 4096 2 /
systemd 1 root txt REG 253,1 1632744 136135 /usr/lib/systemd/systemd
systemd 1 root mem REG 253,1 20064 132877 /usr/lib64/libuuid.so.1.3.0
systemd 1 root mem REG 253,1 265576 134383 /usr/lib64/libblkid.so.1.1.0
systemd 1 root mem REG 253,1 90176 132861 /usr/lib64/libz.so.1.2.7
systemd 1 root mem REG 253,1 157424 132876 /usr/lib64/liblzma.so.5.2.2
systemd 1 root mem REG 253,1 23968 133092 /usr/lib64/libcap-ng.so.0.0.0
systemd 1 root mem REG 253,1 19896 133076 /usr/lib64/libattr.so.1.1.0
8、通过多方征询及材料查阅,理解到在 lsof 4.82 版本后,默认会统计出每个线程的句柄,即默认加上了 - K 参数,这样实现后,以前的命令 lsof -n|awk ‘{print $2}’|sort|uniq -c|sort -nr| head -n 10 统计进去的数据就约等于理论句柄数 * 线程数,也就是咱们后面看到的后果,统计数据数字很大。
9、新 lsof 版本统计句柄正确的语法是 lsof -n -Ki|awk ‘{print $2}’|sort|uniq -c|sort -nr| head -n 10,统计进去后数据失常
[root@greatdb mysql]# lsof -Ki -n| awk '{print $2}' | sort | uniq -c | sort -nr | head
1065 11604
130 1001
91 879
84 8643
84 8641
84 8622
84 8603
84 8570
84 8258
84 8156
10、应用循环的形式,批量创立数据库会话连贯,发现句柄到设置极限后,还会超 45 个句柄数,在此之后手动创立连贯,会始终期待,mysql-err 日志中呈现谬误“Too many open files”
for x in {1..1139}; do nohup mysql -uroot -e 'select sleep(240)' & done
11、在无奈建设新连贯的状况下,查问过程占用句柄数
[root@greatdb mysql]# lsof -p 11604 |wc -l
2205
12、至此找到正确统计过程句柄的办法,计算 MySQL 句柄下限计算形式,并且精确复现异样场景。
3、总结:
- lsof 统计句柄数据,与版本有很大关系,如果是 4.82 之后的版本,统计过程句柄数,须要加上参数 -Ki
- MySQL 启动时占用句柄数 84,当 table_open_cache 设置为 1000 时,除开连贯句柄,最多占用句柄 1065 个,次要蕴含共享库 so、ibd 文件、日志文件、临时文件等,每个链接再独自占用一个句柄
- MySQL 过程的最大句柄数,是参数 open_files_limit + 45,这个是测试进去的,并没有找到具体代码出处
- MySQL 的句柄限度,是由参数 max_connections、table_open_cache 独特影响的,并且不受操作系统限度 (测试了操作系统 ulimit -n 1024 的状况下,MySQL 的 open_files_limit 仍然能够为 2160)
- 文件句柄在线程间是共享的,因而关上一个 ibd 文件,不管有多少 session 拜访,都只会占用一个句柄
参考文章
https://github.com/rapidoid/r…
https://github.com/draios/sys…
https://dev.mysql.com/doc/ref…
Enjoy GreatSQL :)
文章举荐:
技术分享 | MGR 最佳实际 (MGR Best Practice)
https://mp.weixin.qq.com/s/66…
技术分享 | 万里数据库 MGR Bug 修复之路
https://mp.weixin.qq.com/s/Ia…
Macos 零碎编译 percona 及局部函数在 Macos 零碎上运算差别
https://mp.weixin.qq.com/s/jA…
技术分享 | 利用 systemd 治理 MySQL 单机多实例
https://mp.weixin.qq.com/s/iJ…
产品 | GreatSQL,打造更好的 MGR 生态
https://mp.weixin.qq.com/s/By…
产品 | GreatSQL MGR 优化参考
https://mp.weixin.qq.com/s/5m…
对于 GreatSQL
GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。
Gitee:
https://gitee.com/GreatSQL/Gr…
GitHub:
https://github.com/GreatSQL/G…
微信 &QQ 群:
可扫码增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群,亦可间接扫码退出 GreatSQL/MGR 交换 QQ 群。
本文由博客一文多发平台 OpenWrite 公布!