一次由于磁盘空间满导致的MySQL故障
一、故障描述:
今天早上起来,发现收到了邮件报警,提示网站500错误。测试服务器上的网站,凡是没使用数据库的页面能正常打开、而使用到数据库的要么500错误,要么一直在加载中。
二、追根溯源:
1、“show processlist”:
看到这种现象,第一个想到的可能是不良SQL语句导致的锁表,才会导致网站页面一直加载中;连接到数据库,发现“use dbname”语句不能用,也就是不能切换数据库;直接运行“show processlist”查看正在运行的SQL语句,发现有好几百条SQL语句未执行完正常退出,选了两条时间最长的:
2、mysqld日志:
打开MySQL日志(日志文件的路径在“/etc/my.cnf”中指定,默认为“/var/log/mysqld.log”),终于在日志文件底部发现了那么几行错误:
3、清理磁盘空间:
使用“df -h”命令查看当前磁盘空间的使用情况,发现我的“/storage”挂载点的磁盘空间使用率确实达到了“100%”:
三、前因后果:
重启数据库后,发现其他网站正常了,而有一个原来加载很慢的网站,现在刷新直接报500错误了;查看此网站的错误日志,发现依然是提示“sessions”表有错误。
再次连接到MySQL,切换到站点的数据库,执行“select * from sessions limit 1”语句,提示如下错误:
四、总结:
这次的问题非常严重,导致了好几个站点不能正常访问,极大的影响了用户和搜索引擎对网站的信任;主要是由于未预计到用户的图片上传量,未及时扩充磁盘空间,也没有做磁盘空间监控,确实应该深刻检讨。
今天早上起来,发现收到了邮件报警,提示网站500错误。测试服务器上的网站,凡是没使用数据库的页面能正常打开、而使用到数据库的要么500错误,要么一直在加载中。
二、追根溯源:
1、“show processlist”:
看到这种现象,第一个想到的可能是不良SQL语句导致的锁表,才会导致网站页面一直加载中;连接到数据库,发现“use dbname”语句不能用,也就是不能切换数据库;直接运行“show processlist”查看正在运行的SQL语句,发现有好几百条SQL语句未执行完正常退出,选了两条时间最长的:
Id User Host db Command Time State Info 4507153 root localhost:35745 ad Execute 1568 query end INSERT INTO `sessions` (`id`, `modified`, `data`, `lifetime`) VALUES (?, ?, ?, ?) 4507157 root localhost:35752 ad Query 1566 Opening tables DESCRIBE `sessions`可以看出,就是简单的插入操作和显示表结果操作,所以不使用由于SQL语句不良导致的锁表;想“DESCRIBE `sessions`”复原错误现场试试,但是由于切换不了数据库,只能暂时放弃。所以这里找不出问题所在,决定看看MySQL日志看看。
2、mysqld日志:
打开MySQL日志(日志文件的路径在“/etc/my.cnf”中指定,默认为“/var/log/mysqld.log”),终于在日志文件底部发现了那么几行错误:
161203 10:30:39 [Warning] Disk is full writing '/storage/aiezu.com/mysql/ad/sessions.MYI' (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space) 161203 10:30:39 [Warning] Retry in 60 secs. Message reprinted in 600 secs 161203 10:40:39 [Warning] Disk is full writing '/storage/aiezu.com/mysql/ad/sessions.MYI' (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space) 161203 10:40:39 [Warning] Retry in 60 secs. Message reprinted in 600 secs 161203 10:50:39 [Warning] Disk is full writing '/storage/aiezu.com/mysql/ad/sessions.MYI' (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space) 161203 10:50:39 [Warning] Retry in 60 secs. Message reprinted in 600 secs从上面错误提示可以看出,写“sessions”表索引文件时发现磁盘空间不足;
3、清理磁盘空间:
使用“df -h”命令查看当前磁盘空间的使用情况,发现我的“/storage”挂载点的磁盘空间使用率确实达到了“100%”:
[root@aiezu.com ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 20G 11G 7.7G 59% / tmpfs 1.9G 0 1.9G 0% /dev/shm /dev/xvdb1 189G 189G 0G 100% /storage当然,如果即使使用“df -h”命令查看磁盘空间使用率不是“100%”,还得使用“df -i”命令看看磁盘的“inode”使用率,如果“inode”用完,也会导致无法创建文件:
[root@aiezu.com ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 1310720 640191 670529 49% / tmpfs 490142 1 490141 1% /dev/shm /dev/xvdb1 26214408 1451980 24762428 6% /storage发现磁盘空间不足后,删除到一些不重要的上传文件腾出了一半的磁盘空间:
[root@aiezu.com ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 20G 11G 7.7G 59% / tmpfs 1.9G 0 1.9G 0% /dev/shm /dev/xvdb1 189G 98G 91G 51% /storage
三、前因后果:
重启数据库后,发现其他网站正常了,而有一个原来加载很慢的网站,现在刷新直接报500错误了;查看此网站的错误日志,发现依然是提示“sessions”表有错误。
再次连接到MySQL,切换到站点的数据库,执行“select * from sessions limit 1”语句,提示如下错误:
mysql> use ad; Database changed mysql> select * from sessions limit 1; ERROR 145 (HY000): Table './ad/sessions' is marked as crashed and should be repaired看来是由于磁盘空间满的时候导致表文件损坏,经网上搜索,使用下面命令成功将表修复,问题全部得到解决:
[root@aiezu.com ~]# myisamchk -c -r /storage/aiezu.com/mysql/ad/sessions.MYI - recovering (with sort) MyISAM-table '/storage/aiezu.com/mysql/ad/sessions.MYI' Data records: 8 - Fixing index 1 - Fixing index 2
四、总结:
这次的问题非常严重,导致了好几个站点不能正常访问,极大的影响了用户和搜索引擎对网站的信任;主要是由于未预计到用户的图片上传量,未及时扩充磁盘空间,也没有做磁盘空间监控,确实应该深刻检讨。