记一次服务器磁盘报警;原因:Mysql binlog日志太多了;及解决方法。
中午的时候突然收到服务器发的警告,看见我的磁盘使用率已经百分之九十多了,还以为给攻击了或者给docker占满了。
进入后台才发现不是,一看全是 Mysql 的日志给占满了。
解决过程: {#解决过程:}
一、查找占用大的文件 {#一、查找占用大的文件}
使用 du
命令可以查找占用内存大的文件,如果不确定哪个目录占用内存大的可以先从根目录一层一层的查找
|-----------|------------------|
| 1
| du -sh *
|
这里我找到的就是 Mysql 的日志文件,可以看见,日志文件已经占用我6G多的空间了,难怪会报警。
猜想:其他程序问题,一直读写数据库,导致数据库产生了大量的binlog日志,把磁盘空间占满了
二、删除文件 {#二、删除文件}
找到了这些大文件,发现是数据的日志文件,那就直接进入数据库删除吧
|-------------|----------------------------------|
| 1 2
| # 进入数据库 mysql -u root -p
|
mysql 日志的种类,一般来说,日志有五种,分别为:
-
错误日志:-log-err (记录启动,运行,停止mysql时出现的信息)
-
二进制日志:-log-bin (记录所有更改数据的语句,还用于复制,恢复数据库用)
-
查询日志:-log (记录建立的客户端连接和执行的语句)
-
慢查询日志: -log-slow-queries (记录所有执行超过long_query_time秒的所有查询)
-
更新日志: -log-update (二进制日志已经代替了老的更新日志,更新日志在MySQL 5.1中不再使用)
查看这些日志:
|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13
| mysql> show master logs; +------------------+------------+ | Log_name | File_size | +------------------+------------+ | mysql-bin.000008 | 1073748974 | | mysql-bin.000009 | 1073744692 | | mysql-bin.000010 | 1073742182 | | mysql-bin.000011 | 1073743863 | | mysql-bin.000012 | 1073746062 | | mysql-bin.000013 | 1073748330 | | mysql-bin.000014 | 399853232 | +------------------+------------+ 7 rows in set (0.00 sec)
|
查看正在使用的日志文件:
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7
| mysql> show master status; +------------------+-----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+-----------+--------------+------------------+-------------------+ | mysql-bin.000014 | 420566379 | | | | +------------------+-----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
|
当前正在使用的日志文件是 mysql-bin.000014
,那么删除日志文件的时候应该排除掉该文件。
|-------------|--------------------------------------------------------------------|
| 1 2
| # 查看指定binlog文件的内容 show binlog events in 'mysql-bin.000015'
|
rm 删除的时候,一定不能删除正在使用的 binlog 文件。另外用rm 删除的 binlog ,一定要再purge一次,不然数据库无法启动。
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7
| # 删除日志文件的命令:purge binary logs to 'mysql-bin.xxxxxxx'; # 删除除 mysql-bin.000014 以外的日志文件 purge binary logs to 'mysql-bin.000014' ; # 一下干净多了:空间也释放了。 # 它又绿回来了。
|
三、mysql 定时清理日志文件 {#三、mysql-定时清理日志文件}
如果每次等到发现空间不足的时候才去手动删除日志文件,这种方式太麻烦了。
那么,我们就需要设置mysql,让它能自动清理日志文件。
编辑mysql的配置文件,设置expire_logs_days(mysql定时删除日志文件)
|-----------|-------------------------|
| 1
| vim /etc/my.cnf
|
在my.cnf中,添加或修改 expire_logs_days 的值 (这里设置的自动删除时间为10天, 默认为0不自动删除)
|-----------|-----------------------------|
| 1
| expire_logs_days=10
|
修改后,重启 mysql 就会生效。
但是,在生产环境中,重启mysql数据库往往会付出很高的代价。
于是,可以在不重启 mysql 的情况下,修改expire_logs_days值
登陆到mysql,并输入一下命令。 如下:
|---------------|--------------------------------------------------------------------------------------|
| 1 2 3
| mysql> show variables like '%log%'; mysql> set global expire_logs_days = 10;
|
设置完后,可以通过 show variables like '%log%'; 看到expire_logs_days的值已被修改成10。
注意:通过这种方式设置expire_logs_days虽然不需要重启mysql即可生效,但是该方式在重启mysql之后,值会被恢复。
于是,建议通过mysql命令设置expire_logs_days的同时,也修改/etc/my.cnf下的expire_logs_days=10配置,这样在下次重启mysql的时候,expire_logs_day s也一样是10;
这是数据库的操作日志,例如UPDATE一个表,或者DELETE一些数据,即使该语句没有匹配的数据,这个命令也会存储到日志文件中,还包括每个语句执行的时间,也会记录进去的。
这样做主要有以下两个目的:
1:数据恢复
如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了,想办法挽回损失。
2:主从服务器之间同步数据
主服务器上所有的操作都在记录日志中,从服务器可以根据该日志来进行,以确保两个同步。处理方法分两种情况:
1:只有一个 mysql 服务器,那么可以简单的注释掉这个选项就行了。
vi /etc/my.cnf 把里面的log-bin这一行注释掉,重启 mysql 服务即可。
2:如果你的环境是主从服务器,那么就需要做以下操作了。
A:在每个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪个日志。
B:使用SHOW MASTER LOGS获得主服务器上的一系列日志。
C:在所有的从属服务器中判定最早的日志,这个是目标日志,如果所有的从属服务器是更新的,就是清单上的最后一个日志。
D:清理所有的日志,但是不包括目标日志,因为从服务器还要跟它同步。