问题描述
在出问题的前一瞬间,本地正连着服务器mysql查寻数据,提交补丁代码后,重启tomcat,检查网站运行正常,可就在本地进行数据库查询时,突然提示连接错误。
解决过程
连接总是失败,我不得不去服务器上看看(低配版阿里云服务器)
,putty连接远程服务器。
[第一次尝试]
- 通过
netstat -tulpn
,并没发现mysqld字样,证明mysql服务停止了 - 尝试重启mysql服务,
systemctl start mysql.service
,”大吃一斤”,居然失败,试试systemctl restart mysql.service
,果然还是不行 cd /etc/init.d
, 直接运行mysql (当初把mysql.server放过来改名为mysql),
提示 ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/usr/local/mysql/tmp/mysql.sock’,sock设置放在mysql安装目录的tmp文件夹。cd /usr/local/mysql/tmp
,发现“mysql.sock”变成了*”mysql.sock.lock”*,
被lock住了,将它删掉试试呢,删掉这个sock之后,直接在mysql的bin目录运行mysql,仍然报错,也没能创建新的sock文件,总提示Can’t connect to local MySQL server through socket ‘/usr/local/mysql/tmp/mysql.sock’
- 通过
[第二次尝试]
- 冷静下来,为了专心修复mysql,我把tomcat服务器关掉。再试一下
systemctl restart mysql.servic
,果然没什么鸟用,提示找不到sock,那我重新生成sock文件就可以了,我之前把它删掉了,于是百度”mysql sock文件丢失”,一顿操作也没产生新的sock,直到发现一篇帖子 - 帖子里面说可以自己手动创建,我恍然大悟,赶紧打开mysql.sock.lock (备份了一份),发现此文件只有一个数字,它就是帖子描述的mysql的进程号,由于mysql重启都失败了,这个lock里面的进程号应该已经过时(被lock了嘛),可现在mysql都挂掉了,这也有进程号?
- 抱着试一试的态度,在控制台输入
ps -ef | grep mysqld | grep -v grep
,居然打印出了 root 3232 2037 0 09:02 pts/0 00:00:00 grep –color=auto mysql
我猜想应该是出问题导致服务停掉了,进程并没有死。 - 里面有3232 和 2037两个数字,到底哪个是mysql的进程号呢,据帖子描述,其中一个数字是当前shell窗口的pid,也就是当前ssh窗口的pid,于是在控制台输入
echo $$
,打印出2037,那么3232就是sock的数字,数字填写好重新上传sock (mysql.sock文件),systemctl start mysql.service
, failed again…
- 冷静下来,为了专心修复mysql,我把tomcat服务器关掉。再试一下
[第三次尝试]
- 再次冷静下来,重装算球,算求…,此时是崩溃的。
- 准备删除干净mysql,无意中执行了
find / -name mysql
,发现/run/lock/subsys/mysql,这是什么? - 这个文件是由于mysql异常退出产生,并且它的存在导致mysql无法启动,删除此文件即可解决,此时的我突然有了奔头。
cd /run/lock/subsys/
,rm -rf mysql
输入systemctl start mysql.service
,它在努力启动着,感觉有戏,突然又失败了,伤心之余发现这次的报错信息不一样了, Starting MySQL..The server quit without updating PID file ,这证明了什么?证明了我这顿操作还是有效果,只是效果未达到预期。
[第四次尝试]
- 再次冷静下来,网上漫无目的地搜索着,一篇帖子引起了我的注意,关键语句是”mysql服务器是因为缓存内存不够了导致无缘无故挂掉“,”无缘无故挂掉“这个描述来描述此情此景太过于贴切了,贴切的得让我沉思,难道真是内存问题,内存太关键了,我的低配版的内存只有1G。
- 为了验证我的想法,我到mysql的data目录,找到我的err文件(机器名称.err),从后往前扫,突然看到 [ERROR] InnoDB: Cannot allocate memory for the buffer pool,有种好运来的感觉,再看错误发生时间,就在我修复mysql的期间,这是啥意思?cannot allocate memory,不能分配内存,那就是内存不够啊,于是在控制台执行
free -ml
,空闲内存只剩几十兆。 - 此时我贴切地感觉到好运来了,因为我想起来我的java代码里面有定时任务quartz。我也想起来定时任务启动时创建的是进程,我还想起来,我每次重启tomcat的时候,定时任务会重新初始化一次(因为定时任务启动函数就在web服务器启动时执行的那段java代码里面),那么我重启过多少次tomcat,系统里面就有多少次定时任务的进程。
- 于是我在putty里面敲下
top
,再按shift+m,从大到小显示进程,果然,好几个java进程在吃内存。cd /proc/进程号
,ls -ail
,打印出的exe不出所料地指向jdk安装目录。kill -9 进程号
杀掉进程后,systemctl start mysql.service
,成功了!!!netstat -tulpn
, 里面有3306 mysql,本地连接成功。
心中长吁一口气,辛亏没有卸载。
问题原因
- 内存不足,innodb_buffer_pool_size (这个参数主要作用是缓存innodb表的索引,数据,插入数据时的缓冲)设置过大,我的设置是 innodb_buffer_pool_size=1G
- java定时任务没有关闭机制导致进程数量越来越多。
- quartz的trigger启动放在了tomcat启动开启的servlet里面
解决方案
- kill -s 9 进程号,强制删除进程
- 修改mysql配置文件my.cnf (etc/my.cnf),innodb_buffer_pool_size = 128M
经验
- 要看错误日志
- 资源要及时释放
-