某次,公司内部使用的MySQL测试环境上,开发人员通过SQLyog客户端管理工具连接数据库,命中[1040]错误,提示连接数过多。考虑到开发、测试和运维人员都在使用这套环境,出现这种现象很正常。
笔者猜想,这套MySQL的连接阈值配置估计就是个默认值,针对性地调大即可。为了不耽搁研发进度,赶紧安排实习生进行处理。没曾想,旧坑还没填完,新坑又来了,往下瞧:
处理时发现使用/bin/bash SHELL登录mysql系统用户时,提示:资源不足,登录失败。通常这种情况,做运维的朋友也许或多或少都有遇到过。不是无法派生新的进程或者线程,那大概率就是文件描述符使用达到限制。接着,通过排查,进一步确认。
接触过MySQL的朋友应该都清楚,MySQL是一款单进程、多线程的关系型数据库,当前mysqld主进程派生的总线程数为1036。也不多啊,难道mysql用户的资源限制配置如此之小?
首先,检查下当前mysqld主进程相关阈值限制:
没道理哇,线程数远没有达到软限制或者硬限制的阈值,难道是其他因素引起?带着疑问,先检查下用户资源限制配置文件/etc/security/limits.conf。
终于看到第一个关键信息了,mysql用户的登录限制不管是软限制还是硬限制都是1024,而mysql用户下当前线程数已经达到1036。毫无疑问,首要解决的就是提高用户进程的阈值。结合本文开头的ERROR [1040],检查选项文件中MySQL连接数max_connections阈值配置,并适当调大。
考虑到当前已经无法切至mysql系统用户,资源限制无法动态生效,所以先跟相关方沟通确认并停掉MySQL服务,等线程释放之后,再切入mysql用户,在线生效资源限制。
将mysql用户进程/线程资源软、硬限制分别调至2047和16384,并启动MySQL服务。
本预计到这步,问题应该是可以了掉了。怎料,新的问题依旧源源不断,开发反馈又有很多连接命中报错,具体如下:
线程无法创建,那上文的处理应该存在一些遗留问题,继续排查当前的线程数:
乍一看内存无法分配,还以为是内存耗尽了,其实仍就是mysql用户无法派生新的线程。还有,当前的内存使用相对还是比较空,交换也未产生:
此时,两个疑点萦绕在笔者心头。
其一,su命令切至mysql用户异常,原因可能是之前的配置未生效;
其二,在系统账户root下执行ps -eL都失败,这不应该出现,之前排查时笔者留意过root的进程资源硬限制在31810,不太可能fork不出新进程。
先处理疑点一
由于当前无法在Linux上进行任何操作,强制kill MySQL主线程,释放资源:
果然,之前动态调大mysql资源限制,只有硬限制生效了而软限制并没有。而进程资源又受20-nproc.conf(Linux 6上对应文件是90-nproc.conf)文件所限制,难道有人修改过默认值,立马确认一波:
果不其然,mysql进程资源限制为1024,先将其调整至16384或删掉该条配置(需重启)。
再处理疑点二:
之前排查过程中,笔者确认了在limits.conf并没有配置root资源限制,20-nproc.conf文件更是不限,并且root当前的软硬限制均是31810,具体如下:
在这种场景下,能让笔者很快想到的可能原因只有内核限制,话不多说,先查一把。
原因自然无需多言,显然是被人动过手脚了,将kernel.pid_max内核参数重置,在内核配置文件sysctl.conf中调整为32768,或者直接去掉该参数(需重启),并在线生效。
处理完这些,启动MySQL服务,业务恢复正常。
总之,整个流程处理下来,笔者很“忧伤”,没事做这么多层的用户资源限制做啥。后来,找了个时间和该环境的管理员唠了唠,主要是受限于全局CPU资源紧张,部分环境做了并发访问控制。于是就有了本篇的小记,希望给碰到此类问题的朋友一点思路。
美创运维中心数据库服务团队拥有Oracle ACE 1人、OCM 10余人、数十名Oracle OCP、MySQL OCP、红帽RHCA、中间件weblogic、tuxedo认证、达梦工程师 ,著有《Oracle DBA实战攻略》,《Oracle数据库性能优化方法和最佳实践》,《Oracle内核技术揭秘》等多本数据运维优化书籍。目前运维各类数据库合计2000余套,精通Oracle、MySQL、SQLServer、DB2、PostgreSQL、达梦等主流商业和开源数据库。并成为首批国内达梦战略合作伙伴之一,拥有海量经验和完善的人员培养体系。并同时提供超融合,私有云整体解决方案。
来源:freebuf.com 2020-06-05 15:30:24 by: database
请登录后发表评论
注册