日志管理

错误日志

作用:
记录mysql数据库的一般状态信息及报错信息,是我们对于数据库常规报错处理的常用日志。

默认位置:
$MySQL_base/data/

开启方式:(MySQL安装完后默认开启)

#编辑配置文件
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
log_error=/user/local/mysql/data/$hostname.err
#查看方式
mysql> show variables like 'log_error';

一般查询日志

作用:
记录mysql所有执行成功的SQL语句信息,可以做审计用,但是我们很少开启。

默认位置:
$MySQL_base/data/

开启方式:(MySQL安装完之后默认不开启)

#编辑配置文件
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
general_log=on 或者1
general_log_file=/user/local/mysql/ata/$hostnamel.log
#查看方式
mysql> show variables like '%gen%';

之前说过,undo log记录的是修改之前的数据,提供回滚的能力。redo log记录的是修改之后的数据,提供了崩溃恢复的能力。

那binlog是干什么的呢?binlog记录的是修改之后的数据,用于归档。和redo log日志类似,binlog也有着自己的刷盘策略,通过sync_binlog参数控制:

sync_binlog = 0 :每次提交事务前将binlog写入os cache,由操作系统控制什么时候刷到磁盘
sync_binlog =1 :采用同步写磁盘的方式来写binlog,不使用os cache来写binlog
sync_binlog = N :当每进行n次事务提交之后,调用一次fsync将os cache中的binlog强制刷到磁盘

那么问题来了,binlog和redo log都是记录的修改之后的值,这两者有什么区别呢?有redo log为什么还需要binlog呢?

首先看两者的一些区别:

binlog是逻辑日志,记录的是对哪一个表的哪一行做了什么修改;
redo log是物理日志,记录的是对哪个数据页中的哪个记录做了什么修改,如果你还不了解数据页,你可以理解成对磁盘上的哪个数据做了修改。
binlog是追加写;redo log是循环写,日志文件有固定大小,会覆盖之前的数据。
binlog是Server层的日志;redo log是InnoDB的日志。如果不使用InnoDB引擎,是没有redo log的。

二进制日志

在了解二进制日志之前我们先看下一条SQL如何入库的:

sql-database.gif

作用:
记录已提交的DML事务语句,并拆分为多个事件(event)来进行记录
记录所有DDL、DCL等语句(不会记录DQL语句)
总之,二进制日志会记录所有对数据库发生修改的操作

二进制日志模式:
statement:语句模式(默认模式)。
row:行级模式,数据行的变化过程。
mixed:混合模式(statement+row)推荐。

*优缺点:*

statement模式:

优点:容易被看懂,就是sql语句,记录时不需要太多的磁盘空间。
缺点:记录不够严谨。

row模式:

优点:记录更加严谨。
缺点:有可能会需要更多的磁盘空间,不容易读懂。

binlog的作用:
1)数据的备份恢复
2)数据的复制

开启二进制 ,查看binlog
编写MySQL配置文件
[mysqld]
log-bin=mysql-bin
binlog_format=row 设置binlog模式
expire_logs_days=60 只保留60天的日志

对二进制日志操作

show variables like 'binlog_format' 查看binlog模式
show variables like 'log_bin' 查看binlog是否开启
show binlog events in 'mysql_bin.000001'; show binlog events in 'mysql_binlog.000001' from 414 limit 3; 查看binlog事件
show master logs | show binary logs 显示二进制日志文件


mysqlbinlog --base64-output=decode-rows -vvv /data/mysql_bin.000001 
详细查看row模式下二进制文件

### INSERT INTO `row`.`row01`
### SET
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */ @1等于第一列
### INSERT INTO `row`.`row01`
### SET
###   @1=4 /* INT meta=0 nullable=1 is_null=0 */


root@db02 ~]# ll /data/    mysql重启binlog会刷新000002....以此类推
-rw-rw---- 1 mysql mysql       524 Jun 30 22:28 mysql_bin.000001
-rw-rw---- 1 mysql mysql        19 Jun 30 22:19 mysql_bin.index


事件介绍

1)在binlog中最小的记录单元为事件(event)
2)一个事务会被拆分成多个事件(event)(事务里一条sql语句就是一个event)

事件(event)特性

1)每个event都有一个开始位置(start position)和结束位置(stop position)。
2)所谓的位置就是event对整个二进制的文件的相对位置。
3)对于一个二进制日志中,前120个position是文件格式信息预留空间。
4)MySQL第一个记录的事件,都是从120开始的。结束位置点是143(如果是143说明日志文件没内容)

row模式下数据恢复
准备测试环境
create database db1;
use db1;
create table t1;
insert into t1 values (1),(2),(3);
insert into t1 values (4),(5),(6);
insert into t1 values (7),(8),(9);
删除数据等于1的数据
delete from t1 where id=1;
update t1 set id=10 where id=2;
delete from t1 where id in (3,8);
delete from t1 where id  between 4 and 7;
drop table t1;
drop database db1;
开始恢复
数据恢复到 delete from t1 where id=1;之前

查看binlog日志找到delete 位置点at
mysqlbinlog  [-d 可指定数据库 ]--base64-output=decode-rows -vvv /data/mysql_bin.000002
### DELETE FROM `db1`.`t1`
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at 1050
#210630 23:42:39 server id 2  end_log_pos 1081 CRC32 0xd3cf8c5f 	Xid = 60
COMMIT/*!*/;
 at 1081(结束位置点) 全新环境起始位置点120

截取binlog文件
mysqlbinlog [-d 可指定数据库] --start-position=120 --stop-position=1081 /data/mysql_bin.000002 > /tmp/binlog.sql
导入数据
 mysql -uroot -p
 mysql>set sql_log_bin=0 关闭当前会话binlog日志
 mysql>source /tmp/binlog.sql
数据已找回
mysql> select * from t1;
+------+
| id   |
+------+
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
+------+

bin-log 恢复存在问题:

1.多个bin_log日志

2.被误删除的表或者库是很久之前的

删除和刷新binlog
一.根据时间删除日志
	1.临时生效
	set global expire_logs_days=60;
	2.永久生效(修改配置文件)
		[mysqld]
		expire_logs_days=60

二.使用purge命令删除
格式: purge {binary|master} logs {to 'log_name'|before datetime}

purge binary logs to mysql-bin.00006 before '2022-01-05 09:10:00'; 
purge binary logs before now() - interval 3 days 从现在开始只保留3天的
purge binary to 'mysql-bin.000006'; 根据文件名删除(6之前的全部删除)

三.使用reset master
	reset master; 重置binlog 
        
四.刷新binlog
	1.flush logs 刷新binlog日志
	2.重启mysql服务
	3.mysqladmin -uroot -p  -S /tmp/mysql.sock  flush-logs  
	4.达到文件大小上限

慢查询日志

作用: 1.记录mysql数据库中影响性能的sql语句

​ 2.通过分析这个sql语句,改进提高数据库性能

默认位置:

MySQL_basedir/data/hostname-slow.log

开启方式:
vim 配置文件
[mysqld]
slow_query_log= 1  开启慢日志 
slow_query_log_file=/data/slow.log 指定存放位置
long_query_time=5  设定慢查询的阈值(默认10s)
log_queries_not_using_indexes  不使用所以的慢查询日志是否记录
mysqldumpslow分析慢日志
参数:
-s 排序方式: c 记录次数, t 时间, l 查询时间, r 返回记录数 加a 表示倒序 如:at,al,ar
-t  返回前面几条数据
-g 后面可跟正在表达式
mysqldumpslow -s at -t 10 /data/mysql-slow.log 

ps:推荐第三方慢日志分析工具pt-query-digest(percona toolkit),mysqlsla

下载地址https://www.percona.com/downloads/percona-toolkit/3.3.1/binary/redhat/7/