MySQL数据库磁盘爆的主要原因
MySQL磁盘爆的最常见原因之一就是数据量突然增大导致数据库爆,这种原因往往和业务相关。比如应用程序在短时间内生成了大量的数据,如果是突然出现新增大量数据,也有可能是某些测试用例或者压测导致。这种原因导致的数据库磁盘暴涨可以通过清理数据的方式解决,比如清除特定时间段的数据。
建议在测试环境等数据库,进行压力测试或者其他自动化测试时候对数据做特殊的标志,在完成测试后自动清除测试产生的垃圾数据,避免日积月来导致磁盘爆满影响数据库使用。
同时按照数据库日常使用的情况看是否需要对磁盘进行扩容,但是扩容只能缓解,不能根治。
MySQL在日常运行的时候回产生大量的日志文件,这些日志文件也会占用磁盘空间,日积月累可能会产生几百G的日志文件。
MySQL的日志文件主要有以下几种:
- binlog二进制文件通常是占用空间最大的日志类型,这和数据库的使用情况相关。
- error错误日志占用空间大的原因主要体现在长时间的日积月累,没有定时清除导致,比如运行了一两年的数据库,产生的错误日志往往也比较大。
- 慢查询日志慢查询日志通常不会占用太多空间,但是长时间不清理也会出现占用过多的问题,需要定时清理
临时文件
临时文件是数据库运行时候产生的临时性文件,这种临时性文件在运行结束以后会自动释放,但是某些异常情况下如果没有释放会造成比较严重的后果,比如短时间的慢查询语句,这种慢查询执行时间巨长,查询的数据很多,MySQL在内存不够的情况下回临时将中间结果存放在数据库的临时目录下。
处理日志文件导致的磁盘爆满
清理日志文件导致的磁盘爆满比较容易,在确保文件备份转存的前提下可以直接清理文件。使用echo‘’>>host-XXXXX.err等命令可以直接清理这些日志文件。
切记不要直接删除相关的日志文件
查看当前数据库服务器磁盘占用情况可以使用如下命令
查看某个文件夹下的文件磁盘占中情况可以使用du明令参考
#切换到需要查看的路径下使用du-hl
日志文件导致的磁盘爆满可以通过linux命令
echo''>>host-xxxxx.log
处理临时文件导致的磁盘爆满
查看Mysql配置的临时目录
通常MySQL的临时目录在mysql/temp路径下,如果想查看配置的参数,可以使用showvariableslike‘tmpdir’SQL命令
showvariableslike'tmpdir'
临时文件产生的原因
临时文件产生的主要原因是MySQL在执行的时候,对一些大数据量的操作的时候内存无法满足存储需求的时候,MySQL会使用临时文件,比如某个临时表查询出的几百万数据,某个联合查询产生的结果集等。通常情况下MySQL产生的临时文件很小,同时也会及时释放,但是一些异常情况下,比如慢查询,会导致短时间产生大量的临时文件。
下面是一个因为慢查询导致临时目录下产生大量文件的案例。
临时文件产生过多导致磁盘爆满,造成数据库短时故障
数据库崩溃的前兆往往是短时间出现大量IO,CPU暴涨。出现以上征兆的时候数据库就离崩溃不远了,下面这个案例就是。
这个案例中我们发现在某个时间点数据库突然CPU暴涨,而且是持续性暴涨,与此对应的磁盘的IO次数暴增,内存使用暴增。这个时候基本可以判断数据库出现了短时间大量的慢查询。
为什么慢查询会导致磁盘IO暴增?原因是上面说的,数据库在查询的时候使用的临时表或者临时数据如果内存不足以存放的时候,数据库会将这些数据存放在磁盘中,随着慢查询越来越多就会出现集中踩踏的问题,问题愈演愈烈,最终导致数据库卡顿或者崩溃。
上面案例中通过查看数据库执行记录,我们发现的确出现了慢查询积压的情况,使用以下SQL查询可以查询当前正在执行的SQL状态
SELECTid,`state`,user,host,time,`INFO`FROMinformation_schema.processlistwherestateISNOTNULLandstate<>""ORDERBYtimedesc;
上面,你可以看到数据库正在执行超过10W秒的SQL,而且是好几个,这样就不难理解为什么数据库会出现短时间CPU和IO暴增的情况。
解决这些问题的办法就是:kill当前的慢查询,这个办法很管用,但是要记录查询的语句和使用的登录账号和机器,以备兴师问罪。
下面这个语句可以快速生成批量kill语句。
SELECTconcat('kill',id,';')FROMinformation_schema.processlistwhereuser='HispaceCMS'and`COMMAND`='Query'andstateISNOTNULLandstate<>''andDBisnotnullandtime>1000ORDERBYtimedesc
生成以后批量执行就可以了。执行完查询磁盘占用情况,从96%下降到50左右。