一次服务器告警的处理
今天客户在群里一阵@我,说是收到服务器告警短信了。
Usage disk is more than 90% on volume /home...
磁盘空间告急啊。
分析
这台机器上部署了应用和MySQL,日志文件和数据库文件应该是存储的大头,所以立即锁定目标。
为了不泄漏公司机密,以下数据都是我本地的,有内味就行了
我迅速连上公司vpn,ssh到目标主机。
test@Evil:~$ df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 59G 51G 7.7G 87% /
none 59G 51G 7.7G 87% /dev
none 59G 55G 7.7G 92% /home
...
可以看到/home
目录果然超过90%。
test@Evil:~$ du -h -d 1 *
37G Mysql
12G logs/xxx
12G logs
...
查看/home目录下文件的大小,可以看到确实是Mysql和logs占了使用空间的大头。。
清理应用日志
日志文件好整,我获得了客户的授权,一波删除带走
rm -rf logs/xxx/xx-2019-*.log
去年的日志一波带走
test@Evil:~$ du -h -d 1 *
37G Mysql
2G logs/xxx
2G logs
...
看到回了口血,一阵欣慰,毕竟在生产rm -rf
的机会不多。。
mysql binlog
接下来就是搞Mysql了
我知道,它占用空间的大头,也就是数据库文件和binlog文件了,binlog好搞,先易后难。
因为是单点的mysql,所以不用担心什么主备同步问题,带走。。
mysql> reset master; # 清空所有 binlog 文件
mysql ibdata1
mysql的数据文件,我真的是头疼,上次处理相似问题的时候,跟公司的dba讨论了一下,好像是得先导出数据,然后删除ibdata1文件,再启动mysql,导入数据。
大白天的怎么能干这种事儿呢?
只能先分析一波了。
ibdata1是啥呢?
ibdata1是一个用来构建innodb系统表空间的文件,这个文件包含了innodb表的元数据、撤销记录、修改buffer和双写buffer。如果file-per-table选项打开的话,该文件则不一定包含所有表的数据。当innodb_file_per_table选项打开的话,新创建表的数据和索引则不会存在系统表空间中,而是存放在各自表的.ibd文件中。显然这个文件会越来越大,innodb_autoextend_increment选项则指定了该文件每次自动增长的步进,默认是8M.
他为啥会变大?
ibdata1存放数据,索引和缓存等,是MYSQL的最主要的数据。所以随着数据库越来越大,表也会越大,这个无法避免的。
怎么搞掉它?
首先我们把数据库备份下来,然后直接删除ibdata文件(为了保险起见最好先全备一次,做到数据安全和完整),然后再重新导入数据库文件即可!
#停止业务,备份一次全库
mysqldump -u root -p password --all-databases > all_mysql.sql
#备份完成,停止数据库
systemctl stop mariadb 或者 service mysqld stop
#修改配置文件
#在[mysqld]下增加下面配置 innodb_file_per_table=1
#可以重启mysql后
service mysqld restart
#验证
mysql -u root -p password
show variables like '%per_table%';
+-----------------------+-------+
| Variable_name | Value | |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set (0.00 sec)
innodb_file_per_table的状态变为ON
5、删除ibdata1文件和日志
rm -rf ibdata1
rm -rf ib_logfile*
6、恢复数据
mysql -u user -p password
source all_mysql.sql
在MySQL的配置文件[mysqld]部分,增加innodb_file_per_table参数。可以修改InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间。
优点:
- 每个表都有自已独立的表空间。
- 每个表的数据和索引都会存在自已的表空间中。
- 可以实现单表在不同的数据库中移动。
- 空间可以回收(除drop table操作处,表空不能自已回收)
- Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过
alter table TableName engine=innodb;
回缩不用的空间。 - 对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。
- 对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。
缺点:
- 单表增加过大,如超过100个G。
总结
ibdata得等晚上搞了,但愿顺利。
不过这台机器的问题,这么搞也不是长久之际。数据库这块,之前会存日志到库表里,后来客户觉得有日志文件就不用了,写日志到文件的代码已经被我注释了。今晚搞一波ibdata,应该以后增速不会很快了。应用日志一天几百兆,这块得做个定时任务,定期删除日志文件,等下写个脚本,加到系统的crontab里。这样应该能消停了。