1.必要性
在生成环境中,MySQL实例一般都会开启慢日志的,我们可以基于慢日志进行性能分析,但是文件小会逐渐增加,从几十兆到几十G,如此大的文件给我们分析带来了调整。如果我们部署了日志平台,例如通过filebeat +logstash实时读取,当慢日志文件过大也会导致Server性能降低(例如,读取时内存消耗明显)。所以,防止mysql慢查询日志文件过大,进行按天切割很有必要。
2.编辑执行文件chop_slow_log.sh
#!/bin/bash
# The version is defined V.001
# Version ModifyTime ModifyBy Desc
# Ver001 2018-03-02 12:00 Carson.Xu Create the Scripts File
# Desc: This file is used by cron to cut the slow log and remove the history slow log.
#### 部署前应检查slow 所在的路径 (默认为/data/mysql/data/slow.log,否则进行调整)
####time=`date -d yesterday +"%Y-%m-%d"`
time=$(date "+%Y-%m-%d")
rmbaktime=$(date -d '-7 days' "+%Y-%m-%d")
##账号(执行 flush-logs 命令 ,需要有reload权限,允许使用flush语句)
user="用户名"
##应安全要求,账号密码不能同时出现在一个文件中,所以单独存放
passwd=$(cat /data/dbsave/mysql_upwd)
####刷新慢查询日志文件
/usr/local/mysql/bin/mysqladmin -u$user -p$passwd flush-logs slow
####重命名旧慢查询日志
mv /data/mysql/data/slow.log /data/mysql/data/slow-$time.log
####生成新慢查询日志文件
/usr/local/mysql/bin/mysqladmin -u$user -p$passwd flush-logs slow
####删除历史slow.log
rm -rf /data/mysql/data/slow-$rmbaktime.log注意 . 文件设置切割后的慢日志保留7天。
3.设置定时任务(crontab)
46 14 * * * /data/scripts/chop_slow_log.sh >> /data/scripts/chop_slow_log.log 2>&14.相关知识补充
4.1 设置成crontab 报错
单独调试执行chop_slow_log.sh正常,但是设置成定时任务时,就报错。报错信息如下:
/data/scripts/chop_slow_log.sh: line 20: mysqladmin: command not found
/data/scripts/chop_slow_log.sh: line 28: mysqladmin: command not found解决方案是:mysqladmin必须是完成的路径,软链接不可以。
即将文件中的mysqladmin调整为/usr/local/mysql/bin/mysqladmin即可。
4.2 MySQL权限
主要权限列表如下list.
权 限 | 作用范围 | 作 用 |
all | 服务器 | 所有权限 |
select | 表、列 | 选择行 |
insert | 表、列 | 插入行 |
update | 表、列 | 更新行 |
delete | 表 | 删除行 |
create | 数据库、表、索引 | 创建 |
drop | 数据库、表、视图 | 删除 |
reload | 服务器 | 允许使用flush语句 |
shutdown | 服务器 | 关闭服务 |
process | 服务器 | 查看线程信息 |
file | 服务器 | 文件操作 |
grant option | 数据库、表、存储过程 | 授权 |
references | 数据库、表 | 外键约束的父表 |
index | 表 | 创建/删除索引 |
alter | 表 | 修改表结构 |
show databases | 服务器 | 查看数据库名称 |
super | 服务器 | 超级权限 |
create temporary tables | 表 | 创建临时表 |
lock tables | 数据库 | 锁表 |
execute | 存储过程 | 执行 |
replication client | 服务器 | 允许查看主/从/二进制日志状态 |
replication slave | 服务器 | 主从复制 |
create view | 视图 | 创建视图 |
show view | 视图 | 查看视图 |
create routine | 存储过程 | 创建存储过程 |
alter routine | 存储过程 | 修改/删除存储过程 |
create user | 服务器 | 创建用户 |
event | 数据库 | 创建/更改/删除/查看事件 |
trigger | 表 | 触发器 |
create tablespace | 服务器 | 创建/更改/删除表空间/日志文件 |
proxy | 服务器 | 代理成为其它用户 |
usage | 服务器 | 没有权限 |
5.优化方案
5.1 优化背景(why?)
随着公司的业务发展,从库承担的业务也越来越多,相应的慢查询的log也日积月累,越来越大,从节点也需要部署 切割 slow log的任务。
我们发现,部署后,在GTID模式下,主从切换后,主从关系搭不起来了(使用master_auto_position=1,不是文件+位点)。
同样,MHA在线切换后(masterha_master_switch --master_state=alive --conf=/data/mysql_mha/XXXX.cnf --new_master_host=172.XXX.XXX.XXX --new_master_port=3306 --orig_master_is_new_slave),也是新主从报同样的错误(同样主从使用master_auto_position=1,不是文件+位点;使用文件+位点 搭建主从的MHA在线切换没问题,就是说切换后,新主从是好的)。
说明:MHA切换正常,不受影响,切换后新出从报错。
show slave status 显示的错误如下:
....
Slave_IO_Running: No
Slave_SQL_Running: Yes
....
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
.....经过验证分析,错误原因是:
执行如下命令,会产生一个代表事务的GTID,当然,这个GTID也会记录在bin log 中。
/usr/local/mysql/bin/mysqladmin -u$user -p$passwd flush-logs slow即,执行这条命令,实实在在的是一个事务,有GTID,记录在binlog中了,只是 bin log 记录了一个空事务。
通过 show master status 命令查看,我们会看到 Executed_Gtid_Set 值,seqeunce_id有+1,也说明了是一个事务。
如果 flush-logs slow 命令,是在主节点上执行,我们通过 show slave status 命令查看。Executed_Gtid_Set 也发生了变动,这个GTID同步到从节点上了。也就是说,有重放bin log,但是是个空事务(如果不是空事务,那么从节点上也会自动截断 slow log ,但实际不是这样)。
反过来讲,如果 flush-logs slow 在从节点上执行,那么,从节点,就会多了一条 事务,多了一条 GTID(虽然 binlog 对应的GTID是空事务),如果是 每天 执行 一次,那么每天就多一个GTID,从实例不会同步到主实例,主从实例两边事务不一致。而在生产环境中,实例 又会 设置 expire_logs_days (例如 7天),那么expire_logs_days(比如7天)前的 binlog 就会被PURGE掉。这些PURGE掉的binlog就包含了 flush-logs slow 产生的GTID。主从FailOver,重建主从,master_auto_position=1,就会报错,提示包含需要的GTID的binlog已经被PURGE;
5.2 怎么优化(what?)
思路简单,使用不产生 GTID的 flush logs命令,或者在什么条件下 flush logs 不产生GTID。
#!/bin/bash
# The version is defined V.001
# Version ModifyTime ModifyBy Desc
# Ver001 2018-03-02 12:00 Carson.Xu Create the Scripts File
# Desc: This file is used by cron to cut the slow log and remove the history slow log.
#### 部署前应检查slow 所在的路径 (默认为/data/mysql/data/slow.log,否则进行调整)
####time=`date -d yesterday +"%Y-%m-%d"`
time=$(date "+%Y-%m-%d")
rmbaktime=$(date -d '-7 days' "+%Y-%m-%d")
##账号(执行 flush-logs 命令 ,需要有reload权限,允许使用flush语句)
user="用户名"
##应安全要求,账号密码不能同时出现在一个文件中,所以单独存放
passwd=$(cat /data/dbsave/mysql_upwd)
####刷新慢查询日志文件
/usr/local/mysql/bin/mysql -u$user -p$passwd -e"set sql_log_bin=0;flush slow logs;"
####重命名旧慢查询日志
mv /data/mysql/data/slow.log /data/mysql/data/slow-$time.log
####生成新慢查询日志文件
/usr/local/mysql/bin/mysql -u$user -p$passwd -e"set sql_log_bin=0;flush slow logs;"
####删除历史slow.log
rm -rf /data/mysql/data/slow-$rmbaktime.log
















