专栏首页腾讯云数据库专家服务MySQL 案例:"最大连接数"的隐形限制
原创

MySQL 案例:"最大连接数"的隐形限制

问题描述

最近遇到一个比较奇怪的问题,用户反馈云服务器的自建 MySQL 连接数没达到的 max_connections 限制,但是程序侧已经开始报错,无法创建新的连接了。程序端报错信息如下:

perationalError(1135, "Can't create a new thread (errno 11); if you are not out of available memory, 
you can consult the manual for a possible OS-dependent bug")

MySQL 侧的错误日志显示:

Can't create thread to handle new connection(errno= 11)

原因分析

如果是触发了最大连接数的限制,错误信息应该是Too many connections,因此这次遇到的问题应该不是参数方面的问题。

值得注意的是,报错信息中显示了 errorno,这个一般是系统层面抛出的异常 Code,因此看一下这个 11 代表的意义:

OS error code 11: Resource temporarily unavailable

那么问题就比较明显了,这个问题是部分资源不可用引起的,说明是收到了外部(即 Linux)的影响才报错的。那么按照用户的环境,搭建了一个沙盒环境,写了一个简单的 python 脚本(参考附录),发现创建的连接数达到一定的数量之后确认会报错,且抛出的异常信息和用户反馈的信息一致:

root@VM-64-5-debian:~# python3 py_conn.py
hello world
OperationalError(1135, "Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug")
Current MAX_CONNECTION =  32455
5.7.32-log
5.7.32-log
......

在多次尝试过程中,发现一个现象:如果是从 thread_cache 中直接复用的线程是不会触发这个问题的,只有新建连接的时候才会触发。那么追踪了一下 MySQL 创建连接的流程,发现在./sql/conn_handler/connection_handler_per_thread.cc中,以 mysql_thread_create 方法的返回值为条件,会输出这个错误信息。之后以这个方法为入口,最终定位到了原因:调用系统库创建线程的时候出错了。

之后继续查找系统库相关的资料,发现创建线程的数量会受到 Linux 的参数:vm.max_map_count的限制。检查了一下这个参数的作用:

“This file contains the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries.

While most applications need less than a thousand maps, certain programs, particularly malloc debuggers, may consume lots of them, e.g., up to one or two maps per allocation.

The default value is 65536.”

简单来说,进程创建线程的时候会创建一些虚拟内存区域,而这个参数限制了这个区域的数量,因此 MySQL 的可创建的连接数也会受到这个参数的限制。

实际测试一下效果:

Session 1:
root@debian:~# sysctl -w vm.max_map_count=256
vm.max_map_count = 256
root@debian:~# service mysql restart
root@debian:~# mysql57
......
Server version: 5.7.32-log MySQL Community Server (GPL)
......
mysql> select count(*) from performance_schema.threads;
+----------+
| count(*) |
+----------+
|       59 |
+----------+
1 row in set (0.00 sec)

mysql> show variables like '%max_conn%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 100   |
| max_connections    | 151   |
+--------------------+-------+
2 rows in set (0.01 sec)

Session 2:
root@debian:~# python3 py_conn.py
hello world
OperationalError(1135, "Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug")
Current MAX_CONNECTION =  26
5.7.32-log
5.7.32-log
5.7.32-log
5.7.32-log

可以发现调低了这个系统参数之后,尝试创建连接的时候就会报错,而且可用的最大连接数非常低。

总结一下

这个案例属于比较典型的“受牵连”,即 MySQL 因为外部的限制导致问题的发生,DBA 们在排查问题的时候不仅需要考虑到 MySQL 的问题,也要留意是否是外部原因影响了 MySQL 的行为。

附录

Python3.7,py_conn.py。

import MySQLdb
import time

def dbconn():
    try:
        conn = MySQLdb.connect(host="127.0.0.1",user="root",passwd="root",charset="utf8mb4")
        return conn
    except Exception as e:
        print(repr(e))
        return None

def main():
    print("hello world")
    conn_list = []
    num = 65535
    couter = 0
    for counter in range(0,num):
        conn = dbconn()
        if conn is None : break
        conn_list.append(conn) 
    i = 0
    print("Current MAX_CONNECTION = ",counter+1)
    while(True):
        tmp_conn = conn_list[i]
        cursor = tmp_conn.cursor()
        n = cursor.execute("select version()")
        for row in cursor.fetchall():
            for r in row:
                print(r)
        if (i == counter - 1): i = 0
        i = i + 1
        time.sleep (1)

if __name__ == "__main__":
    main()

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MySQL 案例:关于程序端的连接池与数据库的连接数

    Oracle 在 Youtube 分享了一段关于JDBC 连接池的视频,演示了同等业务压力下,不同的连接池线程数设置对数据库性能的影响,HikariCP 转载了...

    王文安@DBA
  • 怎么测试Linux下tcp最大连接数限制详解

    关于TCP服务器最大并发连接数有一种误解就是“因为端口号上限为65535,所以TCP服务器理论上的可承载的最大并发连接数也是65535”。

    砸漏
  • 如何测试Linux下tcp最大连接数限制详解

    关于TCP服务器最大并发连接数有一种误解就是“因为端口号上限为65535,所以TCP服务器理论上的可承载的最大并发连接数也是65535”。

    砸漏
  • 故障分析 | 一次因为超过最大连接数的登陆限制

    在测试某功能时,将 mysql 的最大连接数设置为 120,使用 sysbench 并发 200 插入数据,

    爱可生开源社区
  • mysql的最大连接数问题:pymysql.err.OperationalError: (1040, 'Too many connections')

    pymysql.err.OperationalError: (1040, 'Too many connections') 超出连接数据库最大连接数所致,修改最大...

    Python疯子
  • [mysql] 查看mysql的最大连接数解决too many connection

    陶士涵
  • 怎么查看和修改 MySQL数据库的最大连接数?

    输入SQL语句show variables like '%max_connections%';

    程序员纬度
  • 【MySQL】MGR集群相关简介

    组复制是一种可用于实现容错系统的技术。复制组是一个通过消息传递相互交互的Server集群。复制组由多个Server成员组成,如下图的Master1、Master...

    MySQL技术
  • 执行一条SQL,这之间到底发送了啥

    说到执行SQL,那就不得不谈一谈MySQL的基础模型,以及`server层`与`存储引擎层`之间的功能。这样才方便我们更加了解。执行一条SQL到底发生了啥

    PayneWu
  • 关键的十个MySQL性能优化技巧

    本文转载java知音

    Rookie
  • Nginx限制访问速率和最大并发连接数模块--limit (防止DDOS攻击)

    具体连接请参考 http://tengine.taobao.org/document_cn/http_limit_req_cn.html

    拓荒者
  • 在Linux最大打开文件数限制下 MySQL 对参数的调整

    非root用户运行MySQL,当MySQL配置比较高时,MySQL运行中生效的参数值与配置的值不一样。 这篇文章的目的是为了说明在系统资源不够的情况下,MySQ...

    二狗不要跑
  • iOS8下的UIAlertContoller初探

    1. 任何执行时间长于 wait_timeout或interactive_timeout选项值得备份,都会导致会话被关闭,这也会隐含执行UNLOCK TABL...

    全栈程序员站长
  • Docker 容器明文密码问题解决之道

    Docker 带着 “Dockerize Everything” 的口号,以“软件标准”的姿态展现于世人面前,不断影响大家对于软件的理解。然而现实是否就如想象中...

    CSDN技术头条
  • 没遇到过这十个MySQL 数据库经典错误,你一定不是个好工程师

    笔者在刚开始学习数据库的时候,没少走弯路。经常会遇到各种稀奇古怪的 error 信息,遇到报错会很慌张,急需一个解决问题的办法。跟无头苍蝇一样,会不加思索地把错...

    小小科
  • 12种mysql常见错误总结 +分析示例

    小伙伴们好,我是阿沐!最近呢,正筹备上云工作,需要考虑到很多场景;比如mongo、mysql、redis、splinx等等迁移工作,这就涉及到版本兼容问题;在迁...

    我是阿沐
  • mysql-8.0.11-winx64 安装配置: mysqld --initialize --console MYSQL:ERROR 1045 (28000): Access denied ...

    mysql-8.0.11-winx64 安装配置: mysqld --initialize --console MYSQL:ERROR 1045 (28000...

    一个会写诗的程序员
  • MySQL的匿名账户安全

    在windows中MySql以服务形式存在,在使用前应确保此服务已经启动,未启动可用net start mysql命令启动。而Linux中启动时...

    赵腰静
  • 你确定你的MySQL足够安全吗?

    对于任何一种数据库来说,安全问题都是非常重要的。如果数据库出现安全漏洞,轻则数据被窃取,重则数据被破坏,这些后果对于一些重要的数据库都是非常严重的。下面来从操作...

    Bug开发工程师

扫码关注云+社区

领取腾讯云代金券