由于慢查询日志写满导致的数据库异常

MySQL当慢查询阈值设置的较低时,较容易产生大量的慢查询日志,进而导致数据盘被占满。

原因

MySQL官方并未提供自动定时清理慢查询日志的策略,需要手工干预。

解决方案

方法一:手动刷新日志:

01.关闭慢查询日志:

set global slow_query_log=off;

02.手动刷新慢查询日志:

flush slow logs;

03.重命名慢查询日志文件,删除或压缩:

mv /usr/local/mysql/data/mysql-slow.log /usr/local/mysql/mysql-slow-$(date +%Y-%m-%d).log
gzip -c /usr/local/mysql/mysql-slow-$(date +%Y-%m-%d).log > /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log.gz

04.开启慢查询日志:

set global slow_query_log=on;

方法二:自动刷新日志:

01.创建一个lograte文件:

touch /etc/logrotate.d/mysql

/usr/local/mysql/data/mysql-slow.log {
    size 2G
    dateext
    compress
    missingok
    rotate 30
    notifempty
    delaycompress
    sharedscripts
    nocopytruncate
    create 660 mysql mysql
    postrotate
        /usr/bin/mysql -e 'select @@global.slow_query_log into @sq_log_save; set global slow_query_log=off; select sleep(5); FLUSH SLOW LOGS; select sleep(10); set global slow_query_log=@sq_log_save;'
    endscript
    rotate 250
}
  • size: 保留的文件大小。
  • dateext,定义日志文件后缀为日期格式,比如nginx.log-20190707.gz。
    • 如果该参数被注释掉,切割出来是按数字递增,比如nginx.log-1.gz。
  • missingok,在日志轮循期间,任何错误将被忽略,例如“文件无法找到”之类的错误。
  • notifempty:如果是空文件的话,不进行切割。
  • compress,在轮循任务完成后,已轮循的归档将使用gzip进行压缩。
  • delaycompress,指示logrotate不要将最近的归档压缩,压缩将在下一次轮循周期进行。
  • create 640 nginx adm,以指定的权限和用书属性,创建全新的日志文件,同时logrotate也会重命名原始日志文件。
  • postrotate/endscript,在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。
    • postrotate和endscrip这两个关键字必须单独成行。

02.测试滚动日志是否成功:

logrotate -vf /etc/logrotate.d/mysql
  • 要执行日志滚动,需要在mysql的配置文件中配置账户密码。