日志管理
一、错误日志(log_error)
记录启动\关闭\日常运行过程中,状态信息,警告,错误
错误日志配置
默认就是开启的: /数据路径下/hostname.err
手工设定:
Master [(none)]>select @@log_error;
vim /etc/my.cnf
log_error=/var/log/mysql.log
log_timestamps=system
重启生效
show variables like 'log_error';
二、binlog(binary logs):二进制日志
(1)备份恢复必须依赖二进制日志
(2)主从环境必须依赖二进制日志
2.1 binlog配置 (5.7必须加server_id)
注意:MySQL默认是没有开启二进制日志的。
基础参数查看:
开关:
[(none)]>select @@log_bin;
日志路径及名字
[(none)]>select @@log_bin_basename;
服务ID号:
[(none)]>select @@server_id;
二进制日志格式:
[(none)]>select @@binlog_format;
双一标准之二:
[(none)]>select @@sync_binlog; 每次事务提交,必然保证binlog cache中的日志落到磁盘
2.1.1 创建日志目录
mkdir /data/binlog
chown -R mysql.mysql /data/binlog
2.1.2 修改配置文件
vim /etc/my.cnf
server_id=6 ----->5.6中,单机可以不需要此参数
log_bin=/data/binlog/mysql-bin
binlog_format=row
2.1.3 重启数据库生效
/etc/init.d/mysqld restart
2.1.4 参数说明
server_id=3306
主要是在主从复制过程中必须要加的,但是在5.7版本中,要用以下参数(log_bin),开启binlog日志,即使是单机也是必加的
log_bin=/data/binlog/mysql-bin
(1)开启二进制日志功能
(2)设置二进制日志目录及名称前缀
binlog_format=row
binlog是SQL层的功能。记录的是变更SQL语句,不记录查询语句。
2.2 日志文件查看
2.2.1 查看日志的开启情况
log_bin参数设置的路径,可以找到二进制日志
Master [(none)]>show variables like '%log_bin%';
+---------------------------------+------------------------------+
| Variable_name | Value |
+---------------------------------+------------------------------+
| log_bin | ON |
| log_bin_basename | /data/binlog/mysql-bin |
| log_bin_index | /data/binlog/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+------------------------------+
6 rows in set (0.01 sec)
2.2.2 查看一共多少个binlog
Master [(none)]>show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 154 |
+------------------+-----------+
1 row in set (0.01 sec)
1.flush logs滚动一个新的日志
Master [(none)]>flush logs; 刷新出新的日志文件,往最新的日志里写
Query OK, 0 rows affected (0.03 sec)
Master [(none)]>flush logs;
Query OK, 0 rows affected (0.01 sec)
Master [(none)]>show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 201 |
| mysql-bin.000002 | 201 |
| mysql-bin.000003 | 154 |
+------------------+-----------+
3 rows in set (0.00 sec)
2.2.3 查看mysql正在使用的日志文件
show master status;
Master [(none)]>show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
Master [(none)]>
file:当前MySQL正在使用的文件名
Position:最后一个事件的结束位置号
2.2.4 模拟binlog恢复数据
show binlog events in ‘mysql-bin.000001’ limit 100
mysql -e "show binlog events in ‘mysql-bin.000001’ " | grep xxx
1.建库建表插入数据
2.模拟数据
create database bindb charset utf8mb4;
use bindb
create table t1(id int);
begin;
insert into t1 values(1),(2),(3);
commit;
drop database bindb;
3.数据恢复
在没备份的情况下,通过日志来恢复。
通过日志找到建库这个时间点,和drp之前的时间点
3.1 分析binlog
起点:
终点:
mysql>show master status
file:当前MySQL正在使用的文件名
mysql>show binlog events in 'mysql-bin.filenumXX'
关注点在Pos
通过上面的语句找到建库create那一行的位置
通过上面的语句找到删库drop那一行的位置
4.截取日志
mysqlbinlog --start-position=219 --stop-position=1357 /data/binlog/mysql-bin.filenumXXX > /tmp/bin.sql
5.恢复日志
当前会话临时关闭日志记录。 因为重新导入会产生新的重复的binlog,而且是无用的。所以先关闭记录
mysql>set sql_log_bin=0;
mysql>source /tmp/bin.sql
mysql>set sql_log_bin=1;
6.验证数据
思考:如果是生产环境中,此种恢复手段有什么弊端?
-
binlog记录不单单是一个数据库的操作,可能还会对其他数据库造成影响
解决(-d):mysqlbinlog -d bindb --start-position=219 --stop-position /data/binlog/mysql-bin.000005 -
断断续续的截取
-
数据行多
-
需要的日志再多个文件中分布,跨文件
起点:假如,mysql-bin.000001
终点:一般是最后一个文件,假如,mysql-bin.0002
mysqlbinlog --start-datetime= xx --stop-datetime= xx mysql-bin.000001 mysql-bin.000002
通过时间来截取二进制日志,但一秒内可能发生多次。 -
binlog实际上是数据恢复时配合备份一起恢复数据的手段
2.3 日志内容查看
2.3.1 event查看
Master [binlog]>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.20-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 6 | 154 | |
| mysql-bin.000003 | 154 | Anonymous_Gtid | 6 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 219 | Query | 6 | 319 | create database binlog |
| mysql-bin.000003 | 319 | Anonymous_Gtid | 6 | 384 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 384 | Query | 6 | 486 | use `binlog`; create table t1 (id int) |
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
Log_name:binlog文件名
Pos:开始的position *****
Event_type:事件类型
Format_desc:格式描述,每一个日志文件的第一个事件,多用户没有意义,MySQL识别binlog必要信息
Server_id:mysql服务号标识
End_log_pos:事件的结束位置号 *****
Info:事件内容*****
补充:
SHOW BINLOG EVENTS
[IN 'log_name']
[FROM pos]
[LIMIT [offset,] row_count]
[root@db01 binlog]# mysql -e "show binlog events in 'mysql-bin.000004'" |grep drop
2.3.2 binlog文件内容详细查看
mysqlbinlog /data/mysql/mysql-bin.000006
查看日志解码后的内容:mysqlbinlog --base64-output=decode-rows -vvv /data/binlog/mysql-bin.000003 > /tmp/a.sql 再利用vim 查看
mysqlbinlog -d binlog /data/binlog/mysql-bin.000003
[root@db01 binlog]# mysqlbinlog --start-datetime='2019-05-06 17:00:00' --stop-datetime='2019-05-06 17:01:00' /data/binlog/mysql-bin.000004
2.4 基于Position号进行日志截取
核心就是找截取的起点和终点
--start-position=321
--stop-position=513
mysqlbinlog --start-position=219 --stop-position=1347 /data/binlog/mysql-bin.000003 >/tmp/bin.sql
案例: 使用binlog日志进行数据恢复
模拟:
1.
[(none)]>create database binlog charset utf8;
2.
[(none)]>use binlog;
[binlog]>create table t1(id int);
3.
[binlog]>insert into t1 values(1);
[binlog]>commit;
[binlog]>insert into t1 values(2);
[binlog]>commit;
[binlog]>insert into t1 values(3);
[binlog]>commit;
4.
[binlog]>drop database binlog;
恢复:
[(none)]>show master status ;
[(none)]>show binlog events in 'mysql-bin.000004';
[root@db01 binlog]# mysqlbinlog --start-position=1227 --stop-position=2342 /data/binlog/mysql-bin.000004 >/tmp/bin.sql
[(none)]>set sql_Log_bin=0;
[(none)]>source /tmp/bin.sql
面试案例:
1. 备份策略每天全备,有全量的二进制日志
2.业务中一共10个库,其中一个被误drop了
3. 需要在其他9个库正常工作过程中进行数据恢复
2.5 binlog 维护操作
2.5.1 日志滚动
日志滚动的触发情景:
mysql>flush logs;
mysql>select @@max_binlog_size 达到指定的大小会自动日志滚动一次。
mysqladmin -uroot -p123 flush-logs
mysqldump -F
重启数据库自动滚动
2.5.2 日志删除
注意:不要使用rm命令删除日志。
自动删除机制
mysql>select @@expire_logs_days;
默认是0,单位是天,代表永不删除。
问题:到底设置多少天合适?阈值?
一个全备份周期是x,一般生产一般建议最少2x+1
set global expire_logs_days=15;
手工删除
to表示删除到xxx
mysql> purge binary logs to ‘xxxxx’;
全部清空
mysql>reset master;
比较危险,在主库执行此操作,主从必宕
2.6 binlog日志的GTID新特性
无gtid:
mysqlbinlog --start-position --stop-position
mysqlbinlog -d world --start-position --stop-position
2.6.1 GTID 介绍
5.6 版本新加的特性,5.7中做了加强
5.6 中不开启,没有这个功能.
5.7 中的GTID,即使不开也会有自动生成
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
2.6.2 GTID(Global Transaction ID)
主要是为了主从复制一致性。
它的方便之处:
刷新前:show master status;
刷新:flush logs;
刷新后:show master status; 会发现GTID是连续的
是对于一个已提交事务的编号,并且是一个全局唯一的编号。
它的官方定义如下:
GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29
重要参数介绍:
vim /etc/my.cnf
gtid-mode=on
enforce-gtid-consistency=true
systemctl restart mysqld
select @@gtid_mode;
Master [(none)]>create database gtid charset utf8;
Query OK, 1 row affected (0.01 sec)
Master [(none)]>show master status ;
+------------------+----------+--------------+------------------+----------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000004 | 326 | | | dff98809-55c3-11e9-a58b-000c2928f5dd:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)
Master [(none)]>use gtid
Database changed
Master [gtid]>create table t1 (id int);
Query OK, 0 rows affected (0.01 sec)
Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 | 489 | | | dff98809-55c3-11e9-a58b-000c2928f5dd:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
Master [gtid]>create table t2 (id int);
Query OK, 0 rows affected (0.01 sec)
Master [gtid]>create table t3 (id int);
Query OK, 0 rows affected (0.02 sec)
Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 | 815 | | | dff98809-55c3-11e9-a58b-000c2928f5dd:1-4 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
Master [gtid]>begin;
Query OK, 0 rows affected (0.00 sec)
Master [gtid]>insert into t1 values(1);
Query OK, 1 row affected (0.00 sec)
Master [gtid]>commit;
Query OK, 0 rows affected (0.00 sec)
Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 | 1068 | | | dff98809-55c3-11e9-a58b-000c2928f5dd:1-5 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
Master [gtid]>begin;
Query OK, 0 rows affected (0.00 sec)
Master [gtid]>insert into t2 values(1);
Query OK, 1 row affected (0.00 sec)
Master [gtid]>commit;
Query OK, 0 rows affected (0.01 sec)
Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 | 1321 | | | dff98809-55c3-11e9-a58b-000c2928f5dd:1-6 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
基于DML语句的为一个GTID
2.6.3 基于GTID进行查看binlog
具备GTID后,截取查看某些事务日志:
--include-gtids
--exclude-gtids
--skip-gtids
mysqlbinlog --include-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:1-6' --exclude-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:4' /data/binlog/mysql-bin.000004
2.6.4 GTID日志截取
Info
起点:
单纯看binlog,有点麻烦 一个个看
mysql>show binlog events in ‘mysqk-bin.000002’;
终点:
mysql>show master status;
mysql>show binlog events in ‘mysql-bin.XXXXXX’;
从以上可以得出,GTID范围是 5 - 11
确认范围后确认文件:
确认文件:mysql-bin.000002 mysql-bin.000003 mysql-bin.000004
截取:
cd /data/inlog/
mysqlbinlog --include-gtids='9b8e7056xxxxxxxxxxxxxx:5-11' mysql-bin.000002 mysql-bin.000003 mysql-bin.000004 > /tmp/gtid.sql
如果只想截取1到5,7到10
mysqlbinlog --include-gtids='9b8e7056xxxxxxxxxxxxxx:5-11','9b8e7056xxxxxxxxxxxxxx:7-10' mysql-bin.000002 mysql-bin.000003 mysql-bin.000004 > /tmp/gtid.sql
如果想截取1到14,跳过6
mysqlbinlog --include-gtids='9b8e7056xxxxxxxxxxxxxx:1-14' --exclude-gtids='9b8e7056xxxxxxxxxxxxxx:6' mysql-bin.000002 mysql-bin.000003 mysql-bin.000004 > /tmp/gtid.sql
如果在备份的时候选择 --skip-gtids,就不包含原有的gtid,相当于新的操作,这样恢复的时候也不会去检测到重复出错
cd /data/inlog/
mysqlbinlog --skip-gtids --include-gtids='9b8e7056xxxxxxxxxxxxxx:5-11' mysql-bin.000002 mysql-bin.000003 mysql-bin.000004 > /tmp/gtid.sql
2.6.5 GTID数据恢复
基于2.6.4
mysql>set sql_log_bin=0; 临时关闭日志记录
mysql>source /tmp/gtid.sql
发现报错,因为少了 –skip-gtids 参数
这是因为GTID的幂等性
开启GTID后,MySQL恢复Binlog时,发现GTID存在。重复GTID的事务不会再执行了(即同一操作不能重复)。因此要过滤 gtid信息。
cd /data/inlog/
mysqlbinlog --skip-gtids --include-gtids='9b8e7056xxxxxxxxxxxxxx:5-11' mysql-bin.000002 mysql-bin.000003 mysql-bin.000004 > /tmp/gtid1.sql
mysql>set sql_log_bin=0;
mysql>source /tmp/gtid1.sql
三、慢日志
作用:
记录慢SQL语句的日志,定位低效SQL语句的工具日志
开启慢日志(默认没开启)
开关:
slow_query_log=1
文件位置及名字
slow_query_log_file=/data/mysql/slow.log
设定慢查询时间:
long_query_time=0.1
没走索引的语句也记录:
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
systemctl restart mysqld
mysqldumpslow 分析慢日志
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慢查询可视化