mysql工具类日志(binlog、slowlog、errorlog)
作者:互联网
mysql日志管理
参考https://www.jianshu.com/p/00c54d2832ed
日志设置
工具日志,不同于undo log(事务等)
错误日志(排错、主从错误)--log-error,默认打开,路径datadir/主机名.err,文本格式,重点关注[ERROR]
慢查询日志(优化)--slow_query_log、--long_query_time
二进制日志(主从)--log-bin、--expire-logs-days
目录授权chown -R mysql.mysql /tmp/{errlog,binlog}
一般会定制这些日志的路径,避免数据盘出错,日志也拿不到
查看错误日志路径:select @@log_error,默认应该在./主机名.err,我的在stderr
修改到mysql.mysql有权限的路径,在/etc/my.cnf的[mysqld]下添加log_error=自定义错误日志路径,如/tmp/errlog/mysql.err或mysql.log(自动创建文件),重启生效
二进制日志(binlog),sql层逻辑日志,记录sql语句操作,默认关闭
- 主从复制依赖binlog
- 数据恢复依赖binlog
开启,需要配置参数(/etc/my.cnf的[mysqld]),重启生效:
server_id= 主从复制用,但5.7开始,开启binlog需要配置server_id,1-65535
log_bin= 设置为1,打开binlog功能,生成在默认位置,也可以指定路径如/tmp/binlog/mysql-bin,会打开binglog功能,且按指定路径和名称前缀生存二进制日志,也可以单独设置log_bin和log_bin_basename参数
其中/tmp/binlog是路径,必须mysql.mysql有权限
mysql-bin是前缀,生成日志名称mysql-bin.000001,mysql-bin.000002等,mysql只能使用一个,关注编号最大那个,其他是历史文件(可以设置自动清除的策略),每次重启会生成并使用新的binlog,其中mysql-bin.index列出所有二进制日志文件名称,相当于索引
上面2给参数必须设置,下面可选,binlog_format=row,5.7版本默认配置就是row,可以不设置
innodb_flush_log_at_trx_commit=0:每秒一次将Log Buffer中数据写入到Log File中,并且Flush到磁盘。事务提交不会主动触发写磁盘操作。
innodb_flush_log_at_trx_commit=1:每次事务提交时将Log Buffer数据写入到Log File中,并且Flush到磁盘。
innodb_flush_log_at_trx_commit=2:每次事务提交时将Log Buffer数据写入到Log File中,但不立即Flush到磁盘,MySQL会每秒一次刷新到磁盘。
由于进程调度问题,每条一次操作不能保证每一秒都执行一次。
当innodb_flush_log_at_trx_commit=0时,最近一秒的事务日志存在MySQL的Log Buffer中,无论时MySQL实例停止还是MySQL服务器宕机,都会导致最近一秒的事务日志丢失。
当innodb_flush_log_at_trx_commit=1时,最近一秒的事务日志存在操作系统的文件缓存中,MySQL实例停止不会导致事务日志丢失,但MySQL服务器宕机会导致最近一秒事务日志丢失。
上述的一秒一次刷新,取决于参数innodb_flush_log_at_timeout默认值为1,DDL或其他InnoDB内部操作并不受参数innodb_flush_log_at_trx_commit的限制。
二进制日志概述
二进制日志记录:变更类操作日志,DML增删改(数据)、DDL(增删改表)、DCL(修改权限)
DDL和DCL(如建表create database 库名、alter、drop等),以语句的方式原样记录
DML语句(增删改),记录已提交的事务的SQL语句(未提交或回滚的事务不记录),多种记录格式(statement、row、mixed),通过binlog_format=row参数控制(该参数只控制DML语句),建议使用row。
- statement:SBR模式,语句模式,以SQL语句原样记录命令,可读性强。对于范围操作,日志量少,节省空间(如update t set name='test' where id > 10,SBR只有一条日志,RBR有多少行数据被更新就加多少条日志)。但SBR可能记录不准确,如时间函数,举例insert into t values (1,'test',now());在主从复制或备份还原以后时间字段的值不准确。
- row:RBR模式,行模式,记录一行数据的变化(与redo log区别,redo log记录page页的变化),推荐使用,默认。特点,可读性较弱,范围操作日志量大,但是不会出现记录错误。高可用环境新型架构很多新特性依赖RBR模式,所以建议使用RBR模式。
- mixed:MBR模式,混合模式,由mysql决定选择SBR还是RBR,不可控,不建议使用。
面试:SBR和RBR的区别,选择依据,看上面的笔记即可。
二进制日志的记录单元:
最小单元event,事件,了解了这些,方便有需要截取某些部分日志做数据恢复的需求,比如如删除某几条数据的恢复这种操作,需要知道截取哪些范围的event
不同类型的语句,事件不同
DDL、DCL以SQL形式记录,每个语句(操作)就是一个事件
DML(标准事务语句begin; 语句1;语句2;commit;,这里有4条语句,4个事件),一个事务包含多个语句,每条语句是一个事件
event事件的开始、结束号码(方便从日志中截取想要的event日志事件范围):
操作二进制文件
查找二进制日志是否开启及位置:从配置文件看,或执行show variables like '%log_bin%';
查看二进制日志文件列表:去log_bin的路径下看,或执行show binary logs;
执行flush logs;会滚动出一个新的日志,再执行show binary logs;就会新增加一个文件。
查看正在使用的二进制文件:show master status;
先做些操作记录事件:
create database binlog charset utf8mb4;
use binlog;
create table t1(id int);
insert into t1 values(1);
查看二进制日志的事件:
show master status; 查看使用的二进制日志文件
show binlog events in '文件名' [limit 10]; 查看事件
mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 6 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids | 6 | 154 | |
| mysql-bin.000001 | 154 | Anonymous_Gtid | 6 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 219 | Query | 6 | 335 | create database binlog charset utf8mb4 |
| mysql-bin.000001 | 335 | Anonymous_Gtid | 6 | 400 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 400 | Query | 6 | 501 | use `binlog`; create table t1(id int) |
| mysql-bin.000001 | 501 | Anonymous_Gtid | 6 | 566 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 566 | Query | 6 | 640 | BEGIN |
| mysql-bin.000001 | 640 | Table_map | 6 | 687 | table_id: 108 (binlog.t1) |
| mysql-bin.000001 | 687 | Write_rows | 6 | 727 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000001 | 727 | Xid | 6 | 758 | COMMIT /* xid=16 */ |
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
11 rows in set (0.00 sec)
其中前两行是二进制文件头格式,不用关心,第三行事件POS是154
每行一个事件,pos和end_log_pos是事件开始和结束的位置号码,上一个事件的结束位置是下一个事件的开始位置,开始和结束位置可以作为截取事件的依据,事务截取要从begin到commit才完整。
查看二进制日志文件(二进制格式,用工具查看),Linux下查看日志文件类型:file mysql-bin.000001(mysql复制日志)
[root@VM_0_4_centos ~]# file /tmp/binlog/mysql-bin.000001
/tmp/binlog/mysql-bin.000001: MySQL replication log
查看二进制日志内容:mysqlbinlog mysql-bin.000001;或mysqlbinlog mysql-bin.00001 | grep -v '^SET';不看SET开头的事件
@号码,这是一个事件开始的标志,从#@154开始看,那些SET的事件可以跳过不看,可以对照上面的事件查看结果来看,事件的第一行是注释,注明了事件发生时间
其中行模式记录的sql是base64编码的,要想以解码的方式看,-vvv是使结果更加详细,执行:
mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000001; 执行mysqlbinlog --help可以查看这些参数
# at 687
#200130 21:37:52 server id 6 end_log_pos 727 CRC32 0x209b53a6 Write_rows: table id 108 flags: STMT_END_F
### INSERT INTO `binlog`.`t1`
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
向binlog.t1插入数据,给第一列设置为1,多列分别为@1,@2...
截取二进制日志:
show binlog events in 'mysql-bin.000001';
mysqlbinlog --start-position=起始位置 --stop-position=结束位置 mysql-bin.000001 [ >/tmp/t1.sql];
查看并截取,其中前两行事件的记录依然存在,使用>可以将截取内容输出到sql文件,可以用于数据恢复。
position是事件在二进制文件中的字节占用的位置。
使用二进制日志进行数据恢复(source sql文件;)
误操作或故障以后做数据恢复
drop 库名 表名;删了表和库。
截取二进制日志从库创建到误删除之前的日志,保持为sql文件。
使用source导入sql文件,这部分不需要记录binlog,因为这些日志是从binlog截取的,再记录binlog,以后用binlog做全量恢复会出问题。使用set sql_log_bin=0;在当前会话中临时设置参数将binlog关闭,不影响其它会话,source命令执行完成以后,执行set sql_log_bin=1;修改回来
二进制日志恢复在数据恢复中必不可少,但是有弊端,如数据量大,时间长,只能作为辅助(使用备份+日志)。
若带过滤截取,只能截取某个库的(因为有use可以标识),不能截取某个表的(没有标识,截取较麻烦,如二次开发改写二进制记录的方式,对表的create和增删改操作加上标识):
mysqlbinlog -d 库名 mysql-bin.000001;
gtid模式(全局事务id)
5.6出现的,但不完善,5.7开始企业中建议将二进制日志文件改为gtid模式管理,某些高级功能新特性必须在RBR模式+gtid下才能使用
gtid之前按事件来组织二进制日志的内容,用事件起始、终止position去截取binlog
gtid之后,对binlog中的每个独立事务(不同于innodb的事务)生产一个gtid号码
ddl和dcl,如create database,一条语句就是一个事件event,就是一个事务,就有一个gtid号码
dml,从begin到commit才是一个事务,有一个gtid号码
gtid组成:server-uuid:TID,server-uuid是数据库第一次启动自动生成的,在数据目录下的auto.cnf
文件中(若删除该文件,重启会生成新的,但不要删除和修改它),TID是事务号码,从1开始自增长,不是innodb的事务id
gtid具有幂等性:即用开启了gtid的日志去恢复数据时,系统中存在相同的gtid,若存在重复的gtid自动跳过(执行过的不再执行),会影响binlog的恢复和主从复制
gtid的开启和配置,配置/etc/my.cnf:
gtid-mode=on 开启gtid
enforce-gtid-consistency=true 强制gtid一致性
重启systemctl restart mysqld,gtid开启只影响后面的事务
开启gtid之后操作数据库,执行show master status;在Executed_Gtid_Set列会有值,即server-uuid:TID,其中TID,一个事务是1,n给事务是1-n
执行show binlog events in 'mysql-bin.000001'查看事件,每个事务开始之前有SET设置GTID
截取时使用GTID即可,不用position:
mysqlbinlog --skip-gtids --include-gtids='server-uuid:TID范围,如1-3' mysql-bin.000001 >/tmp/gtid.sql
恢复set sql_log_bin=0; source /tmp/gtid.sql; set sql_log_bin=1;
--skip-gtids参数在导出的时候忽略gtid幂等性(生成的备份不记录原有的gtid信息,恢复时生成新的gtid),否则恢复的时候会检查系统以后的binlog里面是否有要恢复的gtid,有就跳过(幂等性),导致结果不正确。
--include-gtids='server-uuid:TID范围,如1-3',‘server-uuid:TID5',需要导出的事务
--exclude-gtids='server-uuid:TID范围,如1-3',’server-uuid:TID5','server-uuid:TID7',忽略导出的事务
慢查询日志
slowlog,慢查询日志,记录运行慢的sql,优化参考工具,默认关闭
开启,配置/etc/my.cnf的[mysqld]
slow_query_log=1 开关
slow_query_log_file=/tmp/slowlog/slow.log 路径及文件名,/tmp/slowlog需要有mysql.mysql权限,文件名随意
log_query_time=0.1 慢查询时间设定,单位秒,执行select @@long_query_time;(或show variables like '%long_query_time%';)查询默认时间是10.000000秒(不合理,百万数据全表扫描才2-3秒)可以精确到微秒
log_queries_not_using_indexes 没走索引的语句也记录
重启systemctl restart mysqld
构造一张大表,desc 表名;找一个key自带没有值的列(无索引),做查询(全表扫描),构造多条慢查询。
slowlog是文本文件,直接查看即可,记录了超过log_query_time的sql执行记录或没有走索引的查询,包括执行的时间点,库、表、语句、查询时间等。按时间点排序。
过滤,将慢查询日志中,相同的查询语句合并(记录平均查询时间),不同的语句按查询次数(次数多是热语句,优先级高)、Query_time降序排列,使用慢查询分析工具:
mysqldumpslow -s c -t 10 /tmp/slowlog/slow.log -s是排序,c是次数,-s c是按次数排序,-t 10是top 10,自动按查询时间做第二排序维度
拿到需要优化的sql,去做执行计划分析,如分析是否走索引,或是否需要改写sql等
第三方慢查询分析工具(rpm包)
https://www.percona.com/downloads/percona-toolkit/LATEST下载并安装rpm包
安装依赖:
yum install perl-DBD-MYSQL perl-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5
运行:
pt-query-diagest /tmp/slowlog/slow.log
安装Anemometer可基于pt-query-digest将慢查询以网页形式可视化。
标签:binlog,bin.000001,log,errorlog,slowlog,mysql,日志,gtid 来源: https://www.cnblogs.com/kibana/p/12245056.html