[MySQL]-07MySQL日志管理

第1章 错误日志

1.作用

记录数据库启动以来,状态、警告、报错。诊断数据库报错问题。

2.配置

默认: 开启状态。存放在数据目录下(/data/3306/data),名字:主机名.err

3.查看

mysql> select @@log_error;
+-------------+
| @@log_error |
+-------------+
| ./db-51.err |
+-------------+
1 row in set (0.00 sec)

mysql> select @@datadir;
+-------------------+
| @@datadir         |
+-------------------+
| /data/mysql_3306/ |
+-------------------+
1 row in set (0.00 sec)

4.自定义配置

修改配置:

[root@db-51 ~]# vim /etc/my.cnf 
[mysqld]
#新增加参数
log_error=/data/mysql_3306/logs/mysql.err

创建日志目录并更改授权:

[root@db-51 ~]# mkdir /data/mysql_3306/logs/ -p
[root@db-51 ~]# chown -R mysql:mysql /data/mysql_3306/logs/

重启mysql:

systemctl status mysqld.service

重启后报错:

9月 13 17:18:57 db-51 mysqld[1439]: Starting MySQL.2020-09-13T09:18:57.124858Z mysqld_safe error: log-error set to '/data/mysql_3306/logs/mysql.err', however file don't exists. Create writable for user 'mysq

解决方法:

mkdir /data/mysql_3306/logs/ -p
touch /data/mysql_3306/logs/mysql.err
chown -R mysql:mysql /data/mysql_3306/logs/
systemctl restart mysqld.service

第2章 慢日志

1.作用

1.记录MySQL工作过程中较慢的语句
2.默认没有开启,按需求打开。

2.配置

在线配置:

mysql> select @@slow_query_log;      # 开关
mysql> set global slow_query_log=1;  # 在线改
mysql> select @@slow_query_log_file; # 文件位置。离线改。
mysql> select @@long_query_time;     # 慢查询时间设定。
mysql> set global long_query_time=0.1; # 在线设置,最低微秒级别。
mysql> select @@log_queries_not_using_indexes #如果没走索引会被记录
mysql> set global log_queries_not_using_indexes=1; #在线设置 

永久生效:

vim /etc/my.cnf
slow_query_log=1	   #是否启用慢查询日志,1为启用,0为禁用
slow_query_log_file=/data/mysql_3306/logs/slow.log 	#慢日志路径
long_query_time=0.1	   #SQL语句运行时间阈值,执行时间大于参数值的语句才会被记录下来
log_queries_not_using_indexes=1  #将没有使用索引的语句记录到慢查询日志

3.模拟慢语句

select sleep(2) user,host from mysql.user ;
select * from world.city where Name='Groningen';
select * from t100w as a join t100w as b limit N;
select k1,count(*) from t100w where id<N group by k1 having count(*)>N;
select k1,count(*) from t100w where num<N group by k1,k2;
select * from t100w where id<N order by num  desc;
select k1,count(*) from t100w where id<N group by k1,k2;

4.慢日志分析

[root@db01 logs]# mysqldumpslow -s c -t 5 slow.log 
Reading mysql slow query log from slow.log
Count: 7  Time=0.01s (0s)  Lock=0.00s (0s)  Rows=177.1 (1240), root[root]@localhost
  select * from t100w as a join t100w as b limit N
Count: 6  Time=0.57s (3s)  Lock=0.00s (0s)  Rows=33.7 (202), root[root]@localhost
  select k1,count(*) from t100w where id<N group by k1 having count(*)>N
Count: 5  Time=0.59s (2s)  Lock=0.00s (0s)  Rows=893.0 (4465), root[root]@localhost
  select k1,count(*) from t100w where num<N group by k1,k2
Count: 5  Time=0.61s (3s)  Lock=0.00s (0s)  Rows=37.0 (185), root[root]@localhost
  select * from t100w where id<N order by num  desc
Count: 4  Time=0.61s (2s)  Lock=0.00s (0s)  Rows=496.0 (1984), root[root]@localhost
  select k1,count(*) from t100w where id<N group by k1,k2

5.拓展

工具: pt-query-digest

第3章 二进制日志binlog

1.作用

1.数据恢复
2.主从复制

2.记录的内容

记录修改类操作(逻辑日志,类似于SQL记录)
DML: insert update delete
DDL: create drop alter trucate
DCL: grant revoke

3.配置方法

3.1 基础参数查看

mysql> select @@log_bin;
mysql> select @@log_bin_basename;
mysql> select @@server_id;

3.2 设置基础参数

vim /etc/my.cnf
[mysqld]
#新增加参数
server_id=51                              #主机ID,在主从复制会使用
log_bin=/data/mysql_3306/logs/mysql-bin   #开关+文件路径+文件名前缀,最终格式: mysql-bin.000001 

3.3 重启并查看

[root@db-51 ~]# systemctl restart mysqld
[root@db-51 ~]# ll /data/mysql_3306/logs/
总用量 20
-rw-r----- 1 mysql mysql   154 9月  13 17:29 mysql-bin.000001
-rw-r----- 1 mysql mysql    39 9月  13 17:29 mysql-bin.index
-rw-r--r-- 1 mysql mysql 11256 9月  13 17:29 mysql.err

4.binlog内容的记录格式

4.1 事件(event)的记录方式

每个事件:

1.事件描述: 时间戳、server_id、加密方式、开始的位置(start_pos)、结束位置点(end_pos)
2.事件内容: 修改类的操作:SQL 语句 或者 数据行变化。

重点关注:

开始的位置(start_pos)
结束位置点(end_pos)
事件内容 

4.2 二进制日志事件内容格式

查看日志格式:

mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+

作用:

对于DDL、DCL语句,直接将SQL本身记录到binlog中
对于DML : insert、update、delete 受到binlog_format参数控制。
SBR : Statement :  语句模式。之前版本,默认模式
RBR : ROW       : 行记录模式。5.7以后,默认模式
MBR : mixed     :  混合模式。

区别:

Statement、ROW区别: 
update t1 set name='zhangsan' where id<100;

Statement: 记录SQL本身。
ROW: 100个数据行的变化。

Statement日志量少
ROW日志量大

Statement记录不够准确
ROW记录够准确。

例如函数操作:
now() 
rand()

5.binlong查询

5.1 日志文件情况查询

查看所有的日志文件信息

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       154 |
+------------------+-----------+

刷新新日志

mysql> flush logs;
mysql> flush logs;
mysql> flush logs;
mysql> flush logs;
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |   2074265 |
| mysql-bin.000002 |      1181 |
| mysql-bin.000003 |       201 |
| mysql-bin.000004 |       201 |
| mysql-bin.000005 |       154 |
+------------------+-----------+

当前数据库使用的二进制日志

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

5.2 内容查询

数据模拟

create database ku charset utf8mb4;
use ku
create table biao (id int);
insert into biao values(1);
commit;

查看日志事件

mysql> show binlog events in 'mysql-bin.000005';
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000005 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.28-log, Binlog ver: 4 |
| mysql-bin.000005 | 123 | Previous_gtids |         6 |         154 |                                       |
| mysql-bin.000005 | 154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000005 | 219 | Query          |         6 |         323 | create database ku charset utf8mb4    |
| mysql-bin.000005 | 323 | Anonymous_Gtid |         6 |         388 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000005 | 388 | Query          |         6 |         484 | use `ku`; create table biao (id int)  |
| mysql-bin.000005 | 484 | Anonymous_Gtid |         6 |         549 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000005 | 549 | Query          |         6 |         619 | BEGIN                                 |
| mysql-bin.000005 | 619 | Table_map      |         6 |         664 | table_id: 111 (ku.biao)               |
| mysql-bin.000005 | 664 | Write_rows     |         6 |         704 | table_id: 111 flags: STMT_END_F       |
| mysql-bin.000005 | 704 | Xid            |         6 |         735 | COMMIT /* xid=88 */                   |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+

5.3 查看日志内容

查看日志内容

[root@db01 logs]# mysqlbinlog /data/mysql_3306/logs/mysql-bin.000005

Create database日志内容

# at 219
...略
create database ku charset utf8mb4

create table 日志内容

# at 388
...略
create table biao (id int)

insert 操作的日志内容

# at 664
#200914  8:15:15 server id 6  end_log_pos 704 CRC32 0x0a91b6f8  Write_rows: table id 111 flags: STMT_END_F

BINLOG '
E7ZeXxMGAAAALQAAAJgCAAAAAG8AAAAAAAEAAmt1AARiaWFvAAEDAAGlD2wp
E7ZeXx4GAAAAKAAAAMACAAAAAG8AAAAAAAEAAgAB//4BAAAA+LaRCg==
'/*!*/;
# at 704
#200914  8:15:15 server id 6  end_log_pos 735 CRC32 0x1e620e90  Xid = 88
COMMIT/*!*/;

查看解密后的insert

[root@db-51 ~]# mysqlbinlog --base64-output=decode-rows -vv /data/mysql_3306/logs/mysql-bin.000005
.......略
# at 664
#200914  8:15:15 server id 6  end_log_pos 704 CRC32 0x0a91b6f8  Write_rows: table id 111 flags: STMT_END_F
### INSERT INTO `ku`.`biao`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */

6.binlog日志截取及恢复演练

6.1 前提说明

创建或导入数据库之前就配置并开启了binlog

6.2 故障说明

模拟误删库,要求恢复到删库之前

6.3 模拟故障

1.创建库
create database linux5;

2.创建表
use linux5;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(10) NOT NULL COMMENT 'name',
  `age` tinyint(4) NOT NULL COMMENT 'age',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

3.写入数据
insert into user(name,age)
values
('z3',22),
('l4',22),
('w5',22);

4.查看数据
mysql> select * from user;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | z3   |  18 |
|  2 | l4   |  20 |
|  3 | w5   |  21 |
+----+------+-----+

5.模拟删除
drop database linux5;

6.4 恢复思路

第一步:截取从建库以来到删库之前的所有binlog

查看当前处于什么哪个binlog:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     1134 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

第二步: 找到起点,建库的位置点(position)

mysql> show binlog events in 'mysql-bin.000002';
....略
| mysql-bin.000002 |  219 | Query          |         6 |         319 | create database linux5                 

第三步: 找到终点

.....略
| mysql-bin.000002 | 1036 | Query          |         6 |        1134 | drop database linux5                         

导出数据:

mysqlbinlog --start-position=219 --stop-position=1036 /data/mysql_3306/logs/mysql-bin.000002 >/tmp/bin.sql 

将截取的日志进行回放

mysql> set sql_log_bin=0;
mysql> source /tmp/bin.sql;
mysql> set sql_log_bin=1;

7.生产中日志在多个文件中,如何截取?

7.1 场景模拟

flush logs;

#mysql-bin.000005 
show master status ;
create database tongdian charset=utf8mb4;
use tongdian 
create table t1 (id int);
flush logs;

#mysql-bin.000006
show master status ;
insert into t1 values(1),(2),(3);
commit;
flush logs;

#mysql-bin.000007
show master status ;
create table t2(id int);
insert into t2 values(1),(2),(3);
commit;
flush logs;

#mysql-bin.000008
show master status ;
insert into t2 values(11),(22),(33);
commit;
drop database tongdian;

7.2 恢复方法

方法1:分段截取

--start-position    --stop-position 

方法2:时间戳截取

a.找起点: 建库的时间戳

起点posting号

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

通过position过滤时间戳

mysqlbinlog --start-position=951  --stop-position=1073 mysql-bin.000005 |grep -A 1 '^# at 951'

b.找终点

mysql -e "show binlog events in  'mysql-bin.000008'"

c.截取日志

mysqlbinlog  --start-datetime="2020-05-09 17:11:23"  --stop-datetime="2020-05-09 17:14:01"   mysql-bin.000005 mysql-bin.000006 mysql-bin.000007 mysql-bin.000008 >/tmp/data.sql

7.3 binlog其他注意

binlog属于全局日志,日志中有其他库的操作,怎么排除掉?

mysqlbinlog -d oldboy mysql-bin.000008 > /tmp/bin.sql 

binlog中100w个事件,怎么快速找到drop database的位置点?

[root@db01 ~]# mysql -e "show binlog events in 'mysql-bin.000014'" |less
[root@db01 ~]# mysql -e "show binlog events in 'mysql-bin.000014'" |grep

比如删除的库,建库是在2年前操作的。这种情况怎么办?

每天全备,binlog完好的。 
可以使用 全备+binlog方式实现恢复数据故障之前。

8.基于GTID的binlog应用

8.1 GTID全局事务ID

对每个事务,进行单独编号。连续不断进行增长。

8.2 表示方式

server_uuid:N

8.3 GTID配置

查看参数:

mysql> show variables like '%GTID%';       
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery      | ON        |
| enforce_gtid_consistency         | OFF       |
| gtid_executed_compression_period | 1000      |
| gtid_mode                        | OFF       |
| gtid_next                        | AUTOMATIC |
| gtid_owned                       |           |
| gtid_purged                      |           |
| session_track_gtids              | OFF       |
+----------------------------------+-----------+

设置参数:

vim /etc/my.cnf 
[mysqld]
gtid_mode=ON                  #开关
enforce_gtid_consistency=ON   #强制GTID一致性
log_slave_updates=ON          #强制从库更新binlog

重启服务:

systemctl restart mysqld

建议:

5.7版本以后,都开启GTID。最好是搭建环境就开启。

8.4 GTID应用

模拟环境:

a.创建库并查看gtid

mysql> create database gtdb charset utf8mb4;
mysql> show master status ;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000006 |      329 |              |                  | 9b52b744-eb82-11ea-986c-000c294983f8:1 |
+------------------+----------+--------------+------------------+----------------------------------------+

b.创建表并查看gtid

mysql> use gtdb;
mysql> create table t1(id int);
mysql> show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000006 |      491 |              |                  | 9b52b744-eb82-11ea-986c-000c294983f8:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+

c.插入数据并查看

begin;
insert into t1 values(1);
insert into t1 values(2);
insert into t1 values(3);
commit;
show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000006 |      914 |              |                  | 9b52b744-eb82-11ea-986c-000c294983f8:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------+

d.查看事件

mysql> show binlog events in 'mysql-bin.000006';
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000006 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.28-log, Binlog ver: 4                             |
| mysql-bin.000006 | 123 | Previous_gtids |         6 |         154 |                                                                   |
| mysql-bin.000006 | 154 | Gtid           |         6 |         219 | SET @@SESSION.GTID_NEXT= '9b52b744-eb82-11ea-986c-000c294983f8:1' |
| mysql-bin.000006 | 219 | Query          |         6 |         329 | create database gtdb charset utf8mb4                              |
| mysql-bin.000006 | 329 | Gtid           |         6 |         394 | SET @@SESSION.GTID_NEXT= '9b52b744-eb82-11ea-986c-000c294983f8:2' |
| mysql-bin.000006 | 394 | Query          |         6 |         491 | use `gtdb`; create table t1(id int)                               |
| mysql-bin.000006 | 491 | Gtid           |         6 |         556 | SET @@SESSION.GTID_NEXT= '9b52b744-eb82-11ea-986c-000c294983f8:3' |
| mysql-bin.000006 | 556 | Query          |         6 |         628 | BEGIN                                                             |
| mysql-bin.000006 | 628 | Table_map      |         6 |         673 | table_id: 108 (gtdb.t1)                                           |
| mysql-bin.000006 | 673 | Write_rows     |         6 |         713 | table_id: 108 flags: STMT_END_F                                   |
| mysql-bin.000006 | 713 | Table_map      |         6 |         758 | table_id: 108 (gtdb.t1)                                           |
| mysql-bin.000006 | 758 | Write_rows     |         6 |         798 | table_id: 108 flags: STMT_END_F                                   |
| mysql-bin.000006 | 798 | Table_map      |         6 |         843 | table_id: 108 (gtdb.t1)                                           |
| mysql-bin.000006 | 843 | Write_rows     |         6 |         883 | table_id: 108 flags: STMT_END_F                                   |
| mysql-bin.000006 | 883 | Xid            |         6 |         914 | COMMIT /* xid=12 */                                               |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+

8.5 通过GTID方式截取日志

错误的截取命令:

mysqlbinlog --include-gtids='9b52b744-eb82-11ea-986c-000c294983f8:1-3' /data/mysql_3306/logs/mysql-bin.000006 >/tmp/gt.sql

为什么恢复报错?

gtid有“幂等性”检查。GTID的生成,通过Set gtid_next命令实现的。
例如: 
SET @@SESSION.GTID_NEXT= '202628e9-9265-11ea-b4a0-000c29248f69:1'
执行Set命令时,自动检查当前系统是否包含这个GTID信息,如果有就跳过。

正确的方式:

mysqlbinlog --skip-gtids --include-gtids='2ddd7a11-4747-11eb-b274-000c29116b18:1-3' /data/mysql_3306/binlog/mysql-bin.000009 >/tmp/gt_skip.sql

8.6 恢复操作

set sql_log_bin=0;
source /tmp/gt.sql;
set sql_log_bin=1;

9.日志滚动

命令触发:

mysql> flush logs; 
shell# mysqladmin flush-logs
shell# mysql -e "flush logs"
shell# mysqldump -F

自动触发:

mysql> select @@max_binlog_size;
+-------------------+
| @@max_binlog_size |
+-------------------+
|        1073741824 |
+-------------------+

重启数据库,会触发刷新 

10.日志删除

10.1 默认方式

不自动清理。直到空间写满。

10.2 配置自动清理

mysql> select @@expire_logs_days;
最少设置多少天合适? 
参考全备时间周期。
例如: 全备周期是7天。可以保留8天。一般生产中保留两轮备份周期的日志,15天。

设置命令:
set GLOBAL expire_logs_days=7;

10.3 手工清理

Examples:
PURGE BINARY LOGS TO 'mysql-bin.010';
PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
原文地址:https://www.cnblogs.com/alaska/p/14961703.html