欢迎来到 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/rapidoid/issues/105

https://github.com/draios/sysdig/issues/300

https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html

Enjoy GreatSQL

文章推荐:

技术分享 | MGR最佳实践(MGR Best Practice)

https://mp.weixin.qq.com/s/66u5K7a9u8GcE2KPn4kCaA

技术分享 | 万里数据库MGR Bug修复之路

https://mp.weixin.qq.com/s/IavpeP93haOKVBt7eO8luQ

Macos系统编译percona及部分函数在Macos系统上运算差异

https://mp.weixin.qq.com/s/jAbwicbRc1nQ0f2cIa_2nQ

技术分享 | 利用systemd管理MySQL单机多实例

https://mp.weixin.qq.com/s/iJjXwd0z1a6isUJtuAAHtQ

产品 | GreatSQL,打造更好的MGR生态

https://mp.weixin.qq.com/s/ByAjPOwHIwEPFtwC5jA28Q

产品 | GreatSQL MGR优化参考

https://mp.weixin.qq.com/s/5mL_ERRIjpdOuONian8_Ow

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

Gitee:

https://gitee.com/GreatSQL/GreatSQL

GitHub:

https://github.com/GreatSQL/GreatSQL

微信&QQ群:

可扫码添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群,亦可直接扫码加入GreatSQL/MGR交流QQ群。

本文由博客一文多发平台 OpenWrite 发布!

故障案例 | lsof是怎么"影响"MySQL计算打开文件句柄数的的更多相关文章

  1. 故障案例 | 慢SQL引发MySQL高可用切换排查全过程

    作者:梁行 万里数据库DBA,擅长数据库性能问题诊断.事务与锁问题的分析等,负责处理客户MySQL日常运维中的问题,对开源数据库相关技术非常感兴趣. GreatSQL社区原创内容未经授权不得随意使用, ...

  2. 第6章 影响 MySQL Server 性能的相关因素

    前言: 大部分人都一致认为一个数据库应用系统(这里的数据库应用系统概指所有使用数据库的系统)的性能瓶颈最容易出现在数据的操作方面,而数据库应用系统的大部分数据操作都是通过数据库管理软件所提供的相关接口 ...

  3. 影响MySQL性能的五大配置参数

    我们今天主要和大家分享的是对MySQL性能影响关系紧密的五大配置参数,以下就是文章的具体内容描述,希望会给你带来一些帮助在此方面. 以下的文章主要是对MySQL性能影响关系紧密的五大配置参数的介绍,我 ...

  4. 影响 MySQL Server 性能的相关因素

    MySQL 最多的使用场景是WEB 应用,那么我们就以一个WEB 应用系统为例,逐个分析其系统构成,进行经验总结,分析出数据库应用系统中各个环境对性能的影响. 商业需求对性能的影响 这里我们就拿一个看 ...

  5. 表数据量影响MySQL索引选择

    现象 新建了一张员工表,插入了少量数据,索引中所有的字段均在where条件出现时,正确走到了idx_nap索引,但是where出现部分自左开始的索引时,却进行全表扫描,与MySQL官方所说的最左匹配原 ...

  6. mysql计算排名 转

    from :http://www.cnblogs.com/aeiou/p/5719396.html http://www.cnblogs.com/zengguowang/p/5541431.html ...

  7. KVM部署LVS集群故障案例一则

    一.故障现象 KVM部署LVS(Linux Virtual Server)集群后,能够单独以HTTP方式访问RS(Real Server)的实际IP,但无法通过VIP(Virtual IP)访问. 二 ...

  8. MySql(六):影响 MySQL Server 性能的相关因素

    MySQL 最多的使用场景是WEB 应用,那么我们就以一个WEB 应用系统为例,逐个分析其系统构成,进行经验总结,分析出数据库应用系统中各个环境对性能的影响. 一.商业需求对性能的影响 这里我们就拿一 ...

  9. mysql计算时间差函数

    MySql计算两个日期的时间差函数TIMESTAMPDIFF用法,只要用一句SQL语句就可以办到了. MySql计算两个日期的时间差函数TIMESTAMPDIFF用法: 语法: TIMESTAMPDI ...

随机推荐

  1. 11┃音视频直播系统之 WebRTC 进行文本聊天并实时传输文件

    一.RTCDataChannel WebRTC 不但可以让你进行音视频通话,而且还可以用它传输普通的二进制数据,比如说可以利用它实现文本聊天.文件的传输等 WebRTC 的数据通道(RTCDataCh ...

  2. vue中使用echarts的两种方法

    在vue中使用echarts有两种方法一.第一种方法1.通过npm获取echarts npm install echarts --save 2.在vue项目中引入echarts 在 main.js 中 ...

  3. 构建第一个模型:KNN算法(Iris_dataset)

    利用鸢尾花数据集完成一个简单的机器学习应用~万丈高楼平地起,虽然很基础,但是还是跟着书敲了一遍代码. 一.模型构建流程 1.获取数据 本次实验的Iris数据集来自skicit-learn的datase ...

  4. Kafka 消费者解析

    一.消费者相关概念 1.1 消费组&消费者 消费者: 消费者从订阅的主题消费消息,消费消息的偏移量保存在Kafka的名字是__consumer_offsets的主题中 消费者还可以将⾃⼰的偏移 ...

  5. GO GMP协程调度实现原理 5w字长文史上最全

    1 Runtime简介 Go语言是互联网时代的C,因为其语法简洁易学,对高并发拥有语言级别的亲和性.而且不同于虚拟机的方案.Go通过在编译时嵌入平台相关的系统指令可直接编译为对应平台的机器码,同时嵌入 ...

  6. 这个Spring Security登录插件牛啊,验证码、小程序、OAuth2都能快速接入

    上次我们把验证码登录.小程序登录优雅地集成到了Spring Security,很多同学大呼过瘾,相比较一些传统玩法高级了很多.胖哥就赶紧抓住机会举一反三,把几个非标准的OAuth2也接入了进来,主要是 ...

  7. 使用http://start.spring.io/构建maven微服务项目的几个坑及eclipse构建spring boot微服务项目

    一,使用http://start.spring.io/构建maven微服务项目 本来嘛,直接构建的项目导入时没有任何问题的导入就可以运行,可是最近构建好项目,然后导入,种种报错 1.导入之后POM报错 ...

  8. 关于个人全栈项目【臻美IT】博客类出现的问题以及解决方法

    每做一个项目,要记得写下心得哦,别偷懒啊!先上网址:https://www.maomin.club/ 这个项目属于博客类的,因为百度审核的问题就大体做了下,就当来练练手,里面文章链接的是CSDN的博客 ...

  9. 整理orcal常用sql语句

    1.表插入列 alter table XMJ_ONE add column1 NUMBER(38) default 0;comment on column XMJ_ONE.column1 is '字段 ...

  10. 我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言:一个Bug 没想到一个Bug,竟然搞我两次! 我大抵是卷上瘾了,横竖都睡不着,坐起来 ...