导致原因:
出现这种错误明显就是 mysql_connect 之后忘记 mysql_close;
当大量的connect之后,就会出现Too many connections的错误,mysql默认的连接为100个,而什么情况下会出现这种错误呢?
正常的mysql_connect 之后调用 mysql_close()关闭连接
但在连接错误时,会者mysql_real_query()出现错误退出时,可能忘记mysql_close();
所以在程序return 之前一定要判断是否close(),最稳妥的方法就是在写任何函数时都只有一个出口!
MYSQL的数据连接超时时间设置
大规模多线程操作事务的时候,有时候打开一个链接,会进行等待,这时候如果数据库的超时时间设置的过短,就可能会出现,数据链接自动被释放,当然设置过大也不好,慢SQL或其他因素引起的链接过长,导致整个系统被拖慢,甚至挂掉。SO,适当的设置超时时间。设置方法:
SHOW GLOBAL VARIABLES LIKE '%timeout%'
SET GLOBAL wait_timeout=10000 即8小时
前段时间部署在服务器上的网站遇到一个问题:当较长时间没有去访问网站,再次打开时就会报一个数据库连接失败的错误,不管是用ssh开发的项目还是ssm开发的项目,都有这个问题。本篇博客记录这个问题的原因与解决办法。
原因:
由于无论是hibernate还是mybatis开发的都存在这个问题,所以一定不是框架的原因,应该是mysql数据库的问题,查询百度后发现:mysql数据库配置文件存在以下两个参数,是负责管理连接超时的。
1> interactive_timeout:针对交互式连接
2> wait_timeout:针对非交互式连接。
所谓的交互式连接,即在mysql_real_connect()函数中使用了CLIENT_INTERACTIVE选项。说得直白一点,通过mysql客户端连接数据库是交互式连接,通过jdbc连接数据库是非交互式连接。
这两个参数默认都是28800秒,即8小时,也就是超过8小时的连接就会自动失效。这本身并没什么问题,真正的问题是:我们做项目一般使用数据库连接池来获取连接,连接池里的连接可能会较长时间不关闭,等待被使用,这就与mysql连接超时机制起冲突了,当连接池配置永不关闭或者关闭时间超过8小时就会出现我所遇到的问题。
解决办法:
1、修改mysql配置文件里wait_timeout参数,调大一点,然而这治标不治本,因为只要项目里的数据库连接超过一定时间没有被使用还是会出这个问题的,所以不推荐使用这个方法解决。
2、修改数据库连接池的配置,一般的数据库连接池都会带有一个参数:最大空闲时间,修改这个参数的值,不要大于wait_timeout的值即可(也不要等于0)。这里贴出c3p0的配置代码。
<!--最大空闲时间,30分钟内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
- 1
- 2
这个参数是用于修改连接的有效时间的,即超过30分钟没被使用的连接就会被连接池丢弃,当再次需要连接时会重新获取。
查看链接:
./mysqladmin -uroot -p1234.com status
Uptime: 1370150 Threads: 1 (当前连接数) Questions: 79 Slow queries: 0 Opens: 33 Flush tables: 1 Open tables: 26 Queries per second avg: 0.000
./mysql -uroot -p1234.com -e 'show status' | grep -i Threads
Delayed_insert_threads 0
Slow_launch_threads 0
Threads_cached 1
Threads_connected 1
Threads_created 2
Threads_running 1 ##(当前连接数)
mysql> show status like 'Threads%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 1 |
| Threads_connected | 1 |
| Threads_created | 2 |
| Threads_running | 1 | ###当前连接数
+-------------------+-------+
4 rows in set (0.00 sec)
查看最大连接数
[root@xxx bin]# ./mysql -uroot -p1234.com -e 'show variables' | grep max_connections max_connections 500
mysql> show global variables like 'max_conn%';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| max_connect_errors | 10 |
| max_connections | 500 |## 最大连接数
+--------------------+-------+
2 rows in set (0.00 sec)
解决方法:
[root@xxx bin]# gdb -p $(cat /data/mydata/xxx.pid) -ex "set max_connections=500" -batch
[New LWP 7667]
[New LWP 4816]
[New LWP 341]
[New LWP 338]
[New LWP 337]
[New LWP 336]
[New LWP 335]
[New LWP 331]
[New LWP 330]
[New LWP 329]
[New LWP 328]
[New LWP 327]
[New LWP 326]
[New LWP 325]
[New LWP 324]
[New LWP 323]
[New LWP 322]
[Thread debugging using libthread_db enabled]
0x00000035654df1b3 in poll () from /lib64/libc.so.6
mysql> show variables like '%pid%';
+---------------+----------------------+
| Variable_name | Value |
+---------------+----------------------+
| pid_file | /data/mydata/xxx.pid |
+---------------+----------------------+
1 row in set (0.00 sec)
修改完毕后 ,尝试重新进入数据库,并查看链接数
这种方法设置后,只是暂时的,数据库重启后,会变为原来的数值,要想永久,设置完后修改配置文件my.cnf
方法2设置新的最大连接数为200:mysql> set GLOBAL max_connections=200
显示当前运行的Query:mysql> show processlist
显示当前状态:mysql> show status
退出客户端:mysql> exit
这种方法设置后,只是暂时的,数据库重启后,会变为原来的数值,要想永久,设置完后修改配置文件my.cnf
模拟mysql连接数过多
原文链接:https://blog.csdn.net/demonson/article/details/80308853
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
- 发表于 2020-03-01 22:15:09
- 阅读 ( 1213 )
- 分类:数据库