社区编辑申请
注册/登录
MySQL为什么莫名其妙的断开连接以及解决方案!
数据库 MySQL
在部署完成后,网站当时可以正常工作,但是第二天访问网站的时候却会遇到一个500 Server Error。应考虑在程序中进行数据库操作之前检验数据库连接的有效性或者将数据库的autoReconnect属性设置为true来避免这个问题。

前言

最近遇到在将本地的项目部署到服务器上之后遇到的一个奇怪问题:

在部署完成后,网站当时可以正常工作,但是第二天访问网站的时候却会遇到一个500 Server Error。

从日志中可以看出是MySQL数据库出现了异常:

翻译如下:

最后一个数据包在 83827560 ms 之前被成功接收,最后一个数据包在83827560 ms 之前被成功发送。比服务的配置参数wait_timeout的值要长。

日志中给出的建议如下:

翻译如下:

你应考虑在程序中进行数据库操作之前检验数据库连接的有效性或者将数据库的autoReconnect属性设置为true来避免这个问题

关于wait_timeout和autoReconnect下面我们会依次分析介绍!

原因分析

我们进入mysql的命令行查询超时时间:

28800单位是秒转化成小时就是8小时,看出MySQL的默认设置,当一个连接的空闲时间超过8小时后,MySQL就会断开该连接。

所以发现问题出在如果超过这个wait_timeout时间(默认是8小时)对数据库没有任何操作,那么MySQL会自动关闭数据库连接以节省资源。

数据库连接自动断开的问题确实是在第二天发生了,也就是在一个晚上没有对数据库进行操作(显然超过了8小时)的情况下发生的这个问题。

大家用命令show processlist; 可以查看Sleep状态的进程Sleep,同时可以看到每个进程Sleep多久了:

下面介绍下解决和优化办法!

解决方法

1. autoReconnect

这个参数表示在mysql超时断开连接后会自动重新连接,配置的话,只需要在连接mysql的语句写上autoReconnect=true:

jdbc:mysql://127.0.0.1:3306/stock_tweet?autoReconnect=true 

下面是MySQL官网对autoReconnect的解释:

同时可以看到官网不推荐使用这个参数,因为它有一些副作用,具体介绍下:

  • 原有连接上的事务将会被回滚,事务的提交模式将会丢失;
  • 原有连接持有的表的锁将会全部释放;
  • 原有连接关联的会话Session将会丢失,重新恢复的连接关联的将会是一个新的会话Session;
  • 原有连接定义的用户变量将会丢失;
  • 原有连接定义的预编译SQL将会丢失;
  • 原有连接失效,新的连接恢复后,MySQL将会使用新的记录行来存储连接中的性能数据;

2. 修改配置

涉及到两个配置参数interactive_timeout和wait_timeout:

  • wait_timeout 指的是mysql在关闭一个非交互的连接之前所要等待的秒数
  • interactive_time 指的是mysql在关闭一个交互的连接之前所要等待的秒数

对于交互和非交互连接,说得直白一点就是,通过mysql客户端连接数据库是交互式连接,通过jdbc连接数据库是非交互式连接。

配置方法:

(1) 会话方式

msyql> set global wait_timeout=2880000;
msyql> set global interactive_timeout=2880000;

这种方式只对当前会话生效.

(2) 修改配置文件方式

修改/etc/my.cnf文件,在 [mysqld] 节中设置:

之后再重启下服务器就好了!

注意:

  • 将wait_timeout这个值设置得大了,可能会导致空闲连接过多。
  • 如果你的MySQL Server有大量的闲置连接,他们不仅会白白消耗内存,而且如果连接一直在累加而不断开,最终肯定会达到MySQL Server的连接上限数,这会报'too many connections'的错误。

3. 连接池配置

因为连接池的配置也会影响项目和MySQL的连接,所以也需要对数据库连接池的一些配置做一定修改

我们以Spring Boot 2.0默认的数据库连接池HikariCP为例

主要是下面这几个配置

(1) maximum-pool-size:

最大连接数,超过这个数,新的数据库访问线程会被阻,缺省值:10。

常见的错误是设置一个太大的值,连接数多反而性能下降。

参考计算公式是:

#core_count:CPU个数,effective_spindle_count:硬盘个数
connections = ((core_count * 2) + effective_spindle_count)

例如:一个4核,1块硬盘的服务器,连接数 = (4 * 2) + 1 = 9,凑个整数,10就可以了。

(2) minimum-idle:

最小的连接数目。

(3) max-lifetime:

最大的连接时间,用来设置一个connection在连接池中的存活时间。

缺省:30分钟。强烈建议设置比数据库超时时长少一点(MySQL的wait_timeout参数一般为8小时)。

(4) idle-timeout:

一个连接idle状态的最长时间,超时则被释放。

责任编辑:赵宁宁 来源: 月伴飞鱼
相关推荐

2022-04-27 10:02:20

MySQL数据库

2022-04-01 10:08:21

SQL 优化MySQL数据库

2022-05-09 15:08:56

存储厂商NFV领域华为

2022-05-11 15:08:52

驱动开发系统移植

2022-05-16 13:37:12

Sysrv僵尸网络微软

2022-05-20 14:08:13

Web3元宇宙区块链

2022-05-05 15:56:43

数字化转型锐捷网络

2022-04-28 09:46:20

Nginx文件Linux

2022-05-13 11:02:45

数据中心配电设计

2022-04-26 08:10:33

MySQL存储InnoDB

2022-05-24 08:21:16

数据安全API

2022-05-12 14:44:38

数据中心IT云计算

2022-04-20 11:57:30

物联网人工智能

2022-04-02 10:23:12

MySQL数据库

2022-03-16 14:45:18

MySQL慢查询数据库

2022-05-07 10:20:17

truncatedeleteMySQL

2022-04-25 21:25:38

数据模式

2022-04-19 06:20:14

CentOSLinux红帽

2022-05-16 08:33:54

漏洞微软安全补丁

2022-04-21 10:49:30

智慧城市物联网

同话题下的热门内容

分库分表会带来读扩散问题?怎么解决?浅析MySQL日志体系面试官问我 InnoDB 的物理存储结构!InnoDB B-TREE 索引怎么定位一条记录?关于MySQL数据库性能优化方法,看这一篇文章就够了聊聊索引失效的经典场景

编辑推荐

MySQL集群搭建详解如果对MySQL还停留在这个印象,就out了防止服务器宕机时MySQL数据丢失的几种方案MySQL innodb引擎备份工具XtraBackup之二(数据库全备)MySQL优化: Slave延迟很大的优化方法总结
我收藏的内容
点赞
收藏

51CTO技术栈公众号