mysql 数据库DBA课程06_01 日志管理

1、日志管理:
    1.1、错误日志
   作用:排查Mysql运行过程的故障
    1.2、配置
   默认是开启的,默认路径和名称是 数据目录/hostname.err
    查看方法:主要关注,[ERROR]
    select @@log_error;

   1.3、自定义配置错误日志
   vim /etc/my.cnf
    [mysqld]
    log_error=/tmp/mysql3306.log #要保证这个目录要有,而且要有权限
    重启mysql 服务生效。

2、二进制日志(binlog) ******
   2.1、作用
   (1)、主从要依赖于二进制日志
   (2)、数据恢复时需要依赖于 二进制日志
   2.2、配置
    默认二进制日志没有开启。
    开启二进制日志的核心参数
    server_id= 在mysql 5.7中,要开二进制日志,必须要配server_id
    log_bin=1 ,打开二进制日志的开关,系统会放在默认位置
也可以自定义位置:
    log_bin=/data/binlog/mysql-bin #设置二进制日志的路径和前缀名称
    /data/binlog 必须提前创建好而且要有mysq.mysql的权限
    mysql-bin 二进制日志文件名的前缀
   binlog_format=row -----> 5.7版本,默认配置是row ,可以省略
    sync_binlog=1##这也是双"1"参数,每次事务提交都立即刷写binlog到磁盘。

   2.3、二进制日志记录了什么?
   2.3.1、概括
记录的是数据库所有的变更操作日志,DDL 、DCL、DML
   2.3.2、DDL和DCL的记录方法
    以语句的方式,原模原样的记录。比如,create database xy charset utf8mb4; 就是原样记录。
    2.3.3、DML(标准的事务语句,insert ,update,delete)的记录方法
    (1)、记录的是已提交的事务
   (2)、DML语句,记录格式有3种(statement,row,mixed),通过binlog_format=row控制,只能控制DML语句
    说明:
   statement: SBR,语句模式记录日志,做什么命令就记什么命令。可读性强
    row        : RBR,行模式,记录的是数据行的变化5.7默认row,可读性差。
   minxed    : MBR,混合模式,一般不用。由mysql自己决定用那种模式。
面试题:
    SBR和RBR什么区别?怎么选择?
    SBR:可读性比较强,做什么命令,记录什么命令对于范围操作,日志量少但是可能会出现不准确的情况
   比如t1表,10行记录
update t1 set name='zs' where id>5; SBR模式记录只有一条语句,PBR记录的是大于5的每行都会记录。
比如:insert into t1 values(1,'zs',now()); 在恢复的时候会出现数据不准确

RBR:行模式,逐行记录,对于范围操作,日志量大,不会出现记录错误。
高可用环境中的新特性要依赖于RBR模式。
我们公司对数据的严谨性要求较高,也用到了新型的架构,所以选择RBR

2.4、二进制记录单元
2.4.1、event事件,最小单元是event
DDL:create database xy; 对于DDL等语句,每一个语句就是一个事件
DML:一个事务包含了多个语句,每一个语句都是一个事件
begin; #事件1
a         #事件2
b         #事件3
commit; #事件4
2.4.2、event事件,开始 和 结束 号码。
作用,方便我们从日志中截取我们想要的日志事件。
start position
end position
   2.5、二进制日志的管理
   2.5.1 查看二进制 日志位置
    show variables like '%log_bin%';
   2.5.2 查看所有已存在的二进制日志
    show binary logs;
    
   flush logs; 滚动一个新的日志,会新增加一个日志。
   2.5.3、查看正在使用的二进制日志
   默认是最后一个,mysql 只能用一个日志,其他的都是历史。
    show master status;
    2.5.4、查看二进制日志事件
    mysql>create database binlog charset utf8mb4;
    mysql> use binlog;
   mysql> create table t1(id int);
mysql> insert into t1 values(1);
先暂时不提交
重新打开一个窗口,登录mysql
show master status;

show binlog events in 'mysql-bin.000002';


前两行,标识的是,5.7版本的,二进制日志的头格式,每个文件都会有。
每一行都是一个事件


DDL语句,一个语句就是一个事件,一个事件要有一个开始位置,一个结束位置。
未提交的,是不会记录在日志里面。
这时,我们在前一个窗口,提交数据。再在第二个窗口中,查看这个日志。


对于事务,是从begin 开始,到commit;

2.5.5、查看二进制日志的内容:
mysqlbinlog /data/binlog/mysql-bin.000002
mysqlbinlog -d xyz /data/binlog/mysql-bin.000002; ##按库进行过滤日志。
mysqlbinlog /data/binlog/mysql-bin.000002 |grep -v "^SET"




mysqlbinlog --base64-output=decode-rows
-vvv mysql-bin.000002

vvv:表示显示得更加详细

2.5.6、二进制日志截取
先在mysql中查询到 日志的 起始 位置
show binlog events in 'mysql-bin.000002';
mysqlbinlog --start-position=219 --stop-position=335 /data/binlog/mysql-bin.000002 >/tmp/a.sql
2.5.7、通过binlog 恢复数据
模拟数据
create database xyz charset utf8mb4;
use xyz;
create table t1(id int);
insert into t1 values(1),(2);
commit;
模拟故障
drop database xyz;
基于 binlog 恢复
show master status; ##确认现在用的是那个日志文件
show binlog events in 'mysql-bin.000002';


找到起点和终点,进行截取
mysqlbinlog --start-position=1911 --stop-position=2499 /data/binlog/mysql-bin.000002 >/tmp/xyz.sql
恢复:
登录mysql
set sql_log_bin=0; #在此会话中,临时 将二进制日志关闭,不影响其他会话窗口。
因为恢复的时候,也会产生日志,就会有日志冗余,这些日志本来是原有日志文件中的,没必要再次记录。
source /tmp/xyz.sql;
set sql_log_bin=1; ##在把 二进制日志 打开

2.6 binlog的gtid 记录模式的管理
2.6.1、gtid介绍
对于binlog中的每一个事务(),都会生成一个gtid号码
对于DDL、DCL,一个event 就是一个事务,就会有一个gtid号
对于DML语句来讲,从begin 到 commit是一个事务,才会分配一个gtid号
2.6.2、GTID的组成
server_uuid:TID
在你初始化完成后,第一次启动mysql
server_uuid:


auto.cnf 如果被删除的话,重启Mysql后会生成,建议不要去删除。
TID:是一个,自增长的数据,从1开始
2.6.3、GTID的幂等性
如果拿有GTID的日志恢复时,会检查当前系统中,是否有相同的GTID号如果有相同的,自动 跳过。
2.6.4、GTID的开启和配置
vim /etc/my.cnf
[mysqld]
gtid-mode=on ## 开启GTID
enforce-gtid-consistency=true ##强制GTID一致性
2.6.5、查看GTID信息    





开启了GTID,在事件当中,每次操作之前,都加了一个GTID号。
2.6.6、基于GTID ,binlog 恢复
drop database gtid;
查看日志


()截取日志
cd /data/binlog
mysqlbinlog --include-gtids='b3060a95-5e86-11ea-bdb9-000c29e6dd30:1-3' mysql-bin.000003 >/tmp/gtid.sql
恢复:


正确的做法:
导出数据的时候:
cd /data/binlog
mysqlbinlog --skip-gtids
--include-gtids='b3060a95-5e86-11ea-bdb9-000c29e6dd30:1-3' mysql-bin.000003 >/tmp/gtid.sql
--skip-gtids:在导出的时候,忽略原有的GTID信息,恢复时生成新的GTID信息。
恢复:
set sql_log_bin=0;
source /tmp/gtid.sql;
set sql_log_bin=1;
2.6.7、GTID 相关的参数
--skip-gtids
--include-gtids
--exclude-gtids='b3060a95-5e86-11ea-bdb9-000c29e6dd30:6' ##排除 gtid 6
--exclude-gtids='b3060a95-5e86-11ea-bdb9-000c29e6dd30:6', 'b3060a95-5e86-11ea-bdb9-000c29e6dd30:8'
排除多个,用逗号隔开,如果是连续的,直接用 –
二进制日志清理:
自动清理:


vim /etc/my.cnf
expire_logs_days=8,生产环境,保留两个全备周期。如果7天做一次全备,两个全备周期,expire_logs_days=15
设置的依据:至少保留 1轮全备周期长度的过期时间

手工清理二进制日志:
purge binary logs to 'mysql-bin.000010'; ## 删除到mysql-bin.000010为止,就是,删除前9个
purge binary logs before '2019-04-12 22:46:26'; 删除这个时间点以前的日志。
reset master; ### 清除所有日志,又重新从mysql-bin.000001 开始记录。
++++++++++++++++++++++
日志如何滚动
flush logs; 生成一个新的日志
数据库重启,也会生成一个新的日志。
Mysql单个二进制日志文件大小:
show variables like '%max_binlog_size';
vim /etc/my.cnf
max_binlog_size=


3、slow_log 日志
3.1、作用
   记录运行较慢的语句,优化过程中常用的工具日志
3.2、如何配置
slow_query_log=1 ##慢日志开关,默认没有开启。
slow_query_log_file=/data/mysql/slow.log ## 慢日志的存储位置,目录必须要先创建,并且有权限。
##设定慢查询时间
log_query_time=0.1
select @@long_query_time;


## 没走索引的语句 也记录
log_queries_not_using_indexes
vim /etc/my.cnf
##开启慢日志
slow_query_log=1
slow_query_log_file=/data/mysql/slow.log
long_query_time=0.1
log_queries_not_using_indexes
3.3、模拟慢查询
use test;
select num,k1 from t100w where num !=10 order by k1 limit 5;
select num,k1 from t100w where num='16222' order by k1;
select * from t100w where k1='aa' limit 10000,20000;
select * from t100w where k1='aa' limit 100;
3.4、分析慢日志
cd /data/mysql
vim slow.log ## 这是一个文本文件

重新按执行
mysqldumpslow -s c -t 10 /data/mysql/slow.log
-s : sort 排序
c: 次数
-t: top 10 ,前10个
这个工具,实际上会拿执行的时间做第二维度进行排序。


执行计划分析
select * from t100w where k1='S' limit N,N
k1='S' limit N,N 实际上是把k1=后面的条件 和 limit 后面的,合并了

可以随便给一个值,看执行计划分析,有没有走索引。
3.5、第三方工具
https://www.percona.com/downloads/percona-toolkit/LATEST/





wget https://www.percona.com/downloads/percona-toolkit/3.2.0/binary/redhat/7/x86_64/percona-toolkit-3.2.0-1.el7.x86_64.rpm
先安装依赖:
yum install perl-DBI per-DBD-MySQL per-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5 -y
rpm -ivh percona-toolkit-3.2.0-1.el7.x86_64.rpm --force --nodeps


toolkit 工具包中的命令:
pt-query-diagest /data/mysql/slow.log