开局先放一张图
一、日志作用:
排错、数据恢复、优化
1.1错误日志:(默认就是开启状态)
1.1.1查看MySQL错误日志的路径
mysql> select @@log_error;
+---------------+
| @@log_error |
+---------------+
| ./mysql52.err |
+---------------+
1 row in set (0.00 sec)
mysql> select @@datadir;
+-------------------+
| @@datadir |
+-------------------+
| /data/mysql/data/ |
+-------------------+
1 row in set (0.00 sec)
1.1.2错误日志默认路径:
数据路径下/主机名.err /data/mysql/data/mysql52.err
1.1.3修改错误日志路径
vim /etc/my.cnf
log_error=xxxx
重启MySQL生效
1.1.4错误日志使用:
主要查看错误日志中[error]字段的上下文
1.2数据恢复 binlog(binary logs 二进制日志*****)
1.2.1作用:
数据恢复不可缺少的日志文件(默认不开启)
主从复制
1.2.2配置二进制日志说明
log_bin 打开二进制开关和设定存放位置
server_id 5.6单机不需要。5.7必须要加。
注意:二进制日志要和数据分开存放
(日志是用来恢复数据的,你把日志和数据放一块,数据丢了,那日志也就丢了)
(分开放不是放不同的目录,是放在两块磁盘上)
1.2.3具体配置二进制日志
mkdir -p /data/binlog
vim /etc/my.cnf
log_bin=/data/binlog/mysql-bin
server_id=6
重启MySQL生效
注意:mysql-bin可以随便起,作为日志的前缀
server_id 主要作为主从复制时MySQL的唯一标识
1.2.4如何查看配置
show variables like '%log_bin%';
1.2.5binlog记录了什么?
记录了数据库中所有变更类的操作
DDL 定义类语言 原封不动的记录当前DDL语句
DCL 控制类语言 原封不动的记录当前DCL语句
DML (IUD)
前提:已经提交的事务IUD
1.2.6关于binlog记录格式
(1)ROW(5.7 默认) : RBR(ROW based replication) :行记录模式,记录数据行的变化(用户看不懂,需要工具分析)
(2)statement(5.6默认) : SBR(statement based replication) :语句记录模式,语句模式原封不动的记录当前DML。
(3)mixed(混合)MBR(mixed based replication)模式 :以上两种模式的混合
面试题:RBR和SBR的区别
RBR,逐行记录日志,日志量很大,可读性差,但是够严谨,不会出现记录错误
SBR,只记录语句本身,日志量很小,可读性较强,对于函数类的操作,将来恢复时会造成错误
5.7 版本 默认RBR ,是企业建议模式
1.2.7查看当前binlog记录格式
mysql> select @@binlog_format;
5.7默认RBR
1.3二进制日志事件
3.1事件说明
事件是二进制日志的最小记录单元
对于DDL,DCL,一个语句就是一个event
对于DML语句来讲:只记录已提交的事务。
例如以下列子,就被分为了4个event
position号码(为了后期截取日志使用)
begin; 120 - 340
DML1 340 - 460
DML2 460 - 550
commit; 550 - 760
四条语句完成了一个事务,一条语句就是一个event(事件)
3.2event构成
三部分构成:
(1) 事件的开始标识
(2) 事件内容
(3) 事件的结束标识
Position:
开始标识: at 194
结束标识: end_log_pos 254
194? 254?
某个事件在binlog中的相对位置号
位置号的作用是什么?
为了方便我们截取事件
查看二进制日志所在位置
mysql> show variables like '%log_bin%';
[root@mysql52 /data/binlog]# ll 这个路径在my.cnf里设置
total 8
-rw-r----- 1 mysql mysql 154 Jun 25 09:34 mysql-bin.000001 这个编号或者说文件每次重启数据库都会生成新的文件,编号加一
-rw-r----- 1 mysql mysql 30 Jun 25 09:34 mysql-bin.index
用的比较多的查看二进制日志的方法:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 322 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 177 |
| mysql-bin.000002 | 322 |
+------------------+-----------+
2 rows in set (0.00 sec)
有两个(可以有无限个)
log_name: 目前MySQL存在的二进制日志名字
file_size: 目前MySQL用到了哪个position号
查看二进制日志内容
D3L$_6IDZOWP9Q1BO_LQFOG.png
查看二进制日志事件 (event)
show master status; 确认当前在用的binlog
show binlog events in '日志名' 查看x号binlog的事件
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 | |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)
说明
log_name: 日志名
Pos : 事件开始的position****
Event_type : 事件类型
Server_id : 发生在哪台机器上的事件
End_log_pos : 事件结束的位置号*****
Info : 事件内容*****
前154是5.7默认头格式,不能删除
查看二进制日志内容
mysqlbinlog mysql-bin.000002 |grep -v "SET" >/tmp/aa.txt
把二进制日志排除set行(set行无用)打进到一个文件,然后看文件。
mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000002
第二种查看方法(细看)
基于二进制日志数据恢复演练
如何按需截取日志
1.基于position号的截取*****
1.基于position号的截取*****
--start-position=xxx
--stop-position=xxx
截取二进制日志的核心在于找起点和终点
mysql> create database oldboy1; 建库
Query OK, 1 row affected (0.00 sec)
mysql> show binlog events in 'mysql-bin.000002'; 查看二进制日志找到创建语句的号
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 | 4 | Format_desc | 6 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids | 6 | 154 | |
| mysql-bin.000002 | 154 | Anonymous_Gtid | 6 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000002 | 219 | Query | 6 | 322 | create database oldboy1 |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
4 rows in set (0.00 sec)
mysqlbinlog --start-position=219 --stop-position=322 /data/binlog/mysql-bin.000002
mysqlbinlog --start-position=219 --stop-position=322 /data/binlog/mysql-bin.000002 >/tmp/bin.sql
截取对应日志的号到一个文件
mysql> drop database oldboy1; 删库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| oldboy |
+--------------------+
10 rows in set (0.00 sec)
mysql> set sql_log_bin=0; 先关闭记录,就是不记录下边恢复的日志
mysql> source /tmp/bin.sql 恢复
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| oldboy |
| oldboy1 |
+--------------------+
11 rows in set (0.00 sec)
mysql> set sql_log_bin=1; 恢复到记录模式
2. 基于时间点的截取(了解)
--start-datetime
--stop-datetime
for example: 2004-12-25 11:25:56
binlog日志的GTID新特性
什么是GTID(全局事务编号)
5.6 版本新加的特性,5.7中做了加强
5.6 中不开启,没有这个功能.
5.7 中的GTID,即使不开也会有自动生成
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
是对于一个已提交事务的编号,并且是一个全局唯一的编号。
它的官方定义如下:
GTID = source_id : transaction_id
27a3ae28-8dac-11e9-8e94-000c297eff65 : 29
说明:
DDL DCL ,一条语句(事件)就是一个事务,占一个GTID号
DML语句,一个完整的事务(begin --->commint),占一个GTID号
GTID参数配置(开启GTID)
vim /etc/my.cnf
gtid-mode=on
enforce-gtid-consistency=true
重启生效
查看GTID前半部分:
[root@mysql52 /data/mysql/data]# cat auto.cnf
[auto]
server-uuid=27a3ae28-8dac-11e9-8e94-000c297eff65
模拟查看GTID号增长
mysql> create databases gg; 创建一个库
mysql> show master status; 查看GTID对应的事务值
+------------------+----------+--------------+------------------+----------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000003 | 307 | | | 27a3ae28-8dac-11e9-8e94-000c297eff65:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)
mysql-bin.000003 这个东西每次重启数据库都会增加一
最后一列表示GTID号和开启GTID之后,总共发生了多少事务
mysql> use gg 进入
mysql> create table t1 (id int); 建表插入数据
mysql> insert into t1 values(1);
mysql> commit;
mysql> insert into t1 values(2);
mysql> commit;
mysql> insert into t1 values(3);
mysql> commit;
mysql> mysql> show master status; 查看GTID发生了多少事务
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000003 | 1213 | | | 27a3ae28-8dac-11e9-8e94-000c297eff65:1-5 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
mysql> show binlog events in 'mysql-bin.000003';
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000003 | 4 | Format_desc | 6 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 6 | 154 | |
| mysql-bin.000003 | 154 | Gtid | 6 | 219 | SET @@SESSION.GTID_NEXT= '27a3ae28-8dac-11e9-8e94-000c297eff65:1' |
| mysql-bin.000003 | 219 | Query | 6 | 307 | create database gg |
| mysql-bin.000003 | 307 | Gtid | 6 | 372 | SET @@SESSION.GTID_NEXT= '27a3ae28-8dac-11e9-8e94-000c297eff65:2' |
| mysql-bin.000003 | 372 | Query | 6 | 466 | use `gg`; create table t1 (id int) |
| mysql-bin.000003 | 466 | Gtid | 6 | 531 | SET @@SESSION.GTID_NEXT= '27a3ae28-8dac-11e9-8e94-000c297eff65:3' |
| mysql-bin.000003 | 531 | Query | 6 | 601 | BEGIN |
| mysql-bin.000003 | 601 | Table_map | 6 | 644 | table_id: 108 (gg.t1) |
| mysql-bin.000003 | 644 | Write_rows | 6 | 684 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 684 | Xid | 6 | 715 | COMMIT /* xid=15 */ |
| mysql-bin.000003 | 715 | Gtid | 6 | 780 | SET @@SESSION.GTID_NEXT= '27a3ae28-8dac-11e9-8e94-000c297eff65:4' |
| mysql-bin.000003 | 780 | Query | 6 | 850 | BEGIN |
| mysql-bin.000003 | 850 | Table_map | 6 | 893 | table_id: 108 (gg.t1) |
| mysql-bin.000003 | 893 | Write_rows | 6 | 933 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 933 | Xid | 6 | 964 | COMMIT /* xid=17 */ |
| mysql-bin.000003 | 964 | Gtid | 6 | 1029 | SET @@SESSION.GTID_NEXT= '27a3ae28-8dac-11e9-8e94-000c297eff65:5' |
| mysql-bin.000003 | 1029 | Query | 6 | 1099 | BEGIN |
| mysql-bin.000003 | 1099 | Table_map | 6 | 1142 | table_id: 108 (gg.t1) |
| mysql-bin.000003 | 1142 | Write_rows | 6 | 1182 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000003 | 1182 | Xid | 6 | 1213 | COMMIT /* xid=19 */ |
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
21 rows in set (0.00 sec)
结尾就会出现GTID号和对应的事务号
删除库
mysql> drop database gg;
截取事务号,准备恢复
[root@mysql52 ~]# mysqlbinlog --include-gtids='27a3ae28-8dac-11e9-8e94-000c297eff65:1-5' /data/binlog/mysql-bin.000003 >/tmp/ceshi.sql
坑
注意,以上截取的日志文件不能直接恢复
幂等性,GTID检查自己有1-5号事务,就不操作了。
把这些文件拿到别的机器,可以恢复,因为GTID内没有发生过这些事务
正确的截取方法是:
一定要加--skip-gtids参数,不然数据无法恢复
mysqlbinlog --skip-gtids --include-gtids='27a3ae28-8dac-11e9-8e94-000c297eff65:1-5' /data/binlog/mysql-bin.000003 >/tmp/gtid.sql
--skip-gtids 这个参数避免的幂等性,就是告诉GTID不要检查历史事务了,直接操作就行了
临时关闭日志记录功能
mysql> set sql_log_bin=0;
恢复
恢复
mysql> source/tmp/gtid.sql;
别忘了恢复日志记录功能
mysql> set sql_log_bin=1;
截取一到五事务,跳过2和4.
连续跳过的可以写成x-x,不连续只能一个一个写,如下操作
参数是--exclude-gtids
跳过某些gtid不截取(跳过2和4)
[root@db01 ~] mysqlbinlog --skip-gtids --include-gtids='27a3ae28-8dac-11e9-8e94-000c297eff65:1-5' --exclude-gtids='27a3ae28-8dac-11e9-8e94-000c297eff65:2,27a3ae28-8dac-11e9-8e94-000c297eff65:4' /data/binlog/mysql-bin.000003 >/tmp/gtid.sql
二进制日志其他操作
管理二进制日志记录
临时关闭二进制日志记录(会话级别): set sql_log_bin=0
一般用户恢复数据前,恢复数据之后,改回来,或者退出当前会话即可恢复 =1也行
自动清理:
过期 日志 天数
mysql> select @@expire_logs_days;
+--------------------+
| @@expire_logs_days |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.00 sec)
设置日期至少是一个全备周期+1 企业建议是至少两个全备周期+1
设置方法:
临时的,退出重进生效,重启MySQL失效
set global expire_logs_days=8;
永久生效:
vim /etc/my.cnf
expire_logs_days=8
手工清理
注意千万不要rm删除,否则数据库容易起不来
手工清理
PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day;
PURGE BINARY LOGS TO 'mysql-bin.000010'; 000010之前的日志文件全部删除、删除到1000010为止
reset master; 彻底删除所有binlog,从00001开始,超级危险,不要用。。。
日志滚动:
mysql> show variables like '%max_binlog_size%';
+-----------------+------------+
| Variable_name | Value |
+-----------------+------------+
| max_binlog_size | 1073741824 |
+-----------------+------------+
1 row in set (0.00 sec)
查看日志达到多大自动滚动(000001满了,变成000002),一般可以设置为128M自动滚动
手动滚动:让日志编号(00001变成00002.。。)
1.重启数据库
2.flush logs
3.mysqladmin -uroot -p123456 flush-logs
slow_log 慢日志
作用
记录慢SQL语句的日志,定位低效SQL语句的工具日志
开启慢日志(默认没开启)
查看是否开启:
mysql> select @@slow_query_log;
开启慢日志记录:
slow_query_log=1 写入配置文件永久生效 单位是秒,根据具体情况具体定义
set global slow_query_log=1; 临时生效全局会话
查看慢日志默认位置:
mysql> select @@slow_query_log_file;
查看慢日志时间判断(多久查询到算慢语句)
mysql> select @@long_query_time;
+-------------------+
| @@long_query_time |
+-------------------+
| 10.000000 |
+-------------------+
1 row in set (0.00 sec)
关于慢日志设置写入配置文件
slow_query_log=1 开启慢日志记录
slow_query_log_file=/data/mysql/slow.log 慢日志路径
long_query_time=0.1 0.1秒以上为慢语句进行记录
log_queries_not_using_indexes 记录没有走索引的语句
分析慢日志
mysqldumpslow -s c -t 10 /data/mysql/slow.log
第三方工具
https://www.percona.com/downloads/percona-toolkit/LATEST/
yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5
toolkit工具包中的命令:
./pt-query-diagest /data/mysql/slow.log
Anemometer基于pt-query-digest将MySQL慢查询可视化