解决MySQL“ERROR 1040: Too many connections”问题

问题描述

在连接MySQL数据库时,突然出现“ERROR 1040 (HY000): Too many C++onnections”错误。从字面上理解,这通常是由于数据库连接数过多导致的。本文将介绍如何通过修改MySQL配置文件来解决这一问题。

原因分析

MySQL的默认最大连接数是151。当同时连接数据库的客户端数量超过这个限制时,就会出现上述错误。

解决方法

临时配置

如果在生产环境中出现最大连接数不足的情况,建议先使用临时配置,然后在配置文件中进行修改,等待下次重启生效。

当无法登录数据库时,可以先停止连接数据库的应用程序,等待几分钟后再尝试进入数据库。

  1. 查看当前数据库连接数

    mysql> show variables like 'max_connections%';+-----------------+-------+| Variable_name   | Value |+-----------------+-------+| max_connections | 151   |+-----------------+-------+1 row in set (0.00 sec)

  2. 修改数据库连接数(注意:重启后恢复默认)

    mysql> set GLOBAL max_connections=500;Query OK, 0 rows affected (0.00 sec)


  3. 查看修改后的最大连接数

    mysql> show variables like 'max_connections%';+-----------------+-------+| Variable_name   | Value |+-----------------+-------+| max_connections | 500   |+-----------------+-------+1 row in set (0.00 sec)

永久配置

  1. 打开MySQL配置文件(通常为my.cnf

    [MySQLd]部分,找到max_connections字段,将其值修改为500。

    [mysqld]max_connections = 500

    修改完成后,重启MySQL服务器即可使配置生效。


查看MySQL连接状态

  1. 查看连接总数、活跃数和最大并发

    mysql> show status like 'Threads%';+-------------------+-------+| Variable_name     | Value |+-------------------+-------+| Threads_cached    | 0     || Threads_connected | 1     || Threads_created   | 1     || Threads_running   | 2     |+-------------------+-------+4 rows in set (0.01 sec)

    • Threads_connected:表示当前打开的连接数。

    • Threads_running:表示当前活跃的连接数,通常远低于Threads_connected

    • Threads_runningshow processlist的结果一致,表示当前并发数。

  2. 查看线程缓存和创建情况

    如果在MySQL服务器配置文件中设置了thread_cache_size,当客户端断开连接后,服务器会将处理该客户端的线程缓存起来,而不是销毁(前提是缓存数未达上限)。

    mysql>show variables like 'thread_cache_size';+-------------------+-------+| Variable_name     | Value |+-------------------+-------+| thread_cache_size | 100   |+-------------------+-------+1 row in set (0.01 sec)

    如果发现Threads_created值过大,说明MySQL服务器一直在频繁创建线程,这会消耗较多资源。可以适当增加配置文件中的thread_cache_size值。


  3. 查看当前连接列表

    mysql>show processlist;+----+-----------------+-----------+------+---------+------+------------------------+------------------+| Id | User            | Host      | db   | Command | Time | State                  | Info             |+----+-----------------+-----------+------+---------+------+------------------------+------------------+|  5 | event_scheduler | localhost | NULL | Daemon  | 2405 | Waiting on empty queue | NULL             ||  8 | root            | localhost | NULL | Query   |    0 | init                   | show processlist |+----+-----------------+-----------+------+---------+------+------------------------+------------------+2 rows in set (0.00 sec)

    • 如果是root账号,可以看到所有用户的当前连接。

    • 如果是普通账号,只能看到自己占用的连接。

    • show processlist命令默认只列出前100条记录,如果需要查看全部记录,请使用show full processlist

  4. 查看其他状态变量

    mysql>show status like '%变量名%';

    常见的变量及其含义如下:


    • Aborted_clients:由于客户端未正确关闭连接而被放弃的连接数量。

    • Aborted_connects:尝试连接MySQL服务器但失败的次数。

    • Connections:试图连接MySQL服务器的总次数。

    • Created_tmp_tables:执行语句时创建的隐含临时表数量。

    • Delayed_insert_threads:正在使用的延迟插入处理器线程数量。

    • Delayed_writes:通过INSERT DELAYED写入的行数。

    • Delayed_errors:通过INSERT DELAYED写入时发生错误(如重复键值)的行数。

    • Flush_commands:执行FLUSH命令的次数。

    • Handler_delete:请求从表中删除行的次数。

    • Handler_read_first:请求读取表中第一行的次数。

    • Handler_read_key:基于键值读取行的请求次数。

    • Handler_read_next:基于键值读取下一行的请求次数。

    • Handler_read_rnd:基于固定位置读取行的请求次数。

    • Handler_update:请求更新表中行的次数。

    • Handler_write:请求向表中插入行的次数。

    • Key_blocks_used:用于关键字缓存的块数量。

    • Key_read_requests:从缓存中读取键值的请求次数。

    • Key_reads:从磁盘物理读取键值的次数。

    • Key_write_requests:将键值块写入缓存的请求次数。

    • Key_writes:将键值块物理写入磁盘的次数。

    • Max_used_connections:同时使用的最大连接数。

    • Not_flushed_key_blocks:已更改但尚未清空到磁盘的键块数量。

    • Not_flushed_delayed_rows:在INSERT DELAYED队列中等待写入的行数。

    • Open_tables:当前打开的表数量。

    • Open_files:当前打开的文件数量。

    • Open_streams:当前打开的流数量(主要用于日志记录)。

    • Opened_tables:已打开的表数量。

    • Questions:发送到服务器的查询数量。

    • Slow_queries:执行时间超过long_query_time的查询数量。

    • Threads_connected:当前打开的连接数量。

    • Threads_running:当前活跃的线程数量。

    • Uptime:服务器运行时间(单位:秒)。