当前位置: 首页 > 科技观察

MySQL为什么莫名其妙断线及解决方法!

时间:2023-03-13 23:31:37 科技观察

前言最近在部署本地项目到服务器后遇到一个奇怪的问题:部署完成后,网站正常运行,但第二天访问网站时,却遇到了500ServerError。从日志中可以看出MySQL数据库出现异常:翻译如下:最后一个数据包在83827560ms之前成功接收,最后一个数据包在83827560ms之前成功发送。它比服务配置参数wait_timeout的值长。日志中给出的建议如下:译文如下:应该考虑在程序中进行数据库操作前先检查数据库连接的有效性,或者将数据库的autoReconnect属性设置为true来避免这个问题。关于wait_timeout和autoReconnect,我们会依次分析介绍!原因分析我们输入mysql的命令行查询超时时间:28800单位,从秒换算成小时,也就是8小时。我们可以看到MySQL的默认设置。当一个连接空闲时间超过8小时,MySQL就会断开连接。于是发现问题是如果超过这个wait_timeout时间(默认8小时)没有对数据库进行任何操作,MySQL会自动关闭数据库连接以节省资源。第二天确实出现了数据库连接自动断开的问题,也就是一晚上没有对数据库进行任何操作(明显超过8小时)时出现的问题。您可以使用命令showprocesslist;查看进程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>setglobalwait_timeout=2880000;msyql>设置全局交互超时=2880000;该方法只对当前会话有效。(2)修改配置文件方法修改/etc/my.cnf文件,在Set中的[mysqld]段:重启服务器即可!注意:如果wait_timeout的值设置过大,可能会导致空闲连接过多。如果你的MySQLServer有大量的空闲连接,它们不仅会白白消耗内存,而且如果连接一直累积不断开,最终会达到MySQLServer连接数上限,会报'toomanyconnections'错误。3.连接池配置因为连接池的配置也会影响到项目与MySQL的连接,所以也需要对数据库连接池的配置做一些改动。我们以SpringBoot2.0默认的数据库连接池HikariCP为例,主要如下配置(1)maximum-pool-size:最大连接数,超过这个数,新的数据库访问线程将被阻塞,默认值:10.一个常见的错误是设置的值太大,如果连接太多,性能会下降。参考计算公式为:#core_count:CPU个数,effective_spindle_count:硬盘连接数=((core_count*2)+effective_spindle_count)例如:4核1硬盘的服务器,连接数=(4*2)+1=9,凑个整数,10也行。(2)minimum-idle:最小连接数。(3)max-lifetime:最大连接时间,用来设置一个连接在连接池中的存活时间。默认值:30分钟。强烈建议设置的比数据库超时时间小一点(MySQL的wait_timeout参数一般为8小时)。(4)idle-timeout:连接空闲的最长时间,超时后释放。