51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

记一次服务器磁盘报警及解决(Mysql binlog日志太多)

记一次服务器磁盘报警;原因:Mysql binlog日志太多了;及解决方法。

中午的时候突然收到服务器发的警告,看见我的磁盘使用率已经百分之九十多了,还以为给攻击了或者给docker占满了。

进入后台才发现不是,一看全是 Mysql 的日志给占满了。

微信图片编辑_20230329183102 微信截图_20230329184255

解决过程: {#解决过程:}

一、查找占用大的文件 {#一、查找占用大的文件}

使用 du 命令可以查找占用内存大的文件,如果不确定哪个目录占用内存大的可以先从根目录一层一层的查找

|-----------|------------------| | 1 | du -sh * |

这里我找到的就是 Mysql 的日志文件,可以看见,日志文件已经占用我6G多的空间了,难怪会报警。

猜想:其他程序问题,一直读写数据库,导致数据库产生了大量的binlog日志,把磁盘空间占满了

微信截图_20230329184918

二、删除文件 {#二、删除文件}

找到了这些大文件,发现是数据的日志文件,那就直接进入数据库删除吧

|-------------|----------------------------------| | 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' ; # 一下干净多了:空间也释放了。 # 它又绿回来了。 |

微信截图_20230330000648

三、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:清理所有的日志,但是不包括目标日志,因为从服务器还要跟它同步。

赞(1)
未经允许不得转载:工具盒子 » 记一次服务器磁盘报警及解决(Mysql binlog日志太多)