【MySQL篇】MySQL的各种日志,解释清楚Binlog、RedoLog等日志类型

MySQL的各种日志

MySQL中存在着很多种不同类型的日志,都有不同的作用,本文将简单说明日志种类,以及应用场景。

一、日志分类

  • Error Log 错误日志
  • General Log 普通日志
  • Slow Query Log 慢查询日志
  • Binary Log(bin log) 二进制日志
  • Undo Log 回滚日志
  • Redo Log 重写日志

二、日志说明

官方对错误日志的详细说明:dev.mysql.com/doc/refman/...

1.Error Log

用于保存错误日志:主要记录的MySQL在启动、关闭、运行过程中的错误信息。

概览:

ini 复制代码
2020-08-06T14:25:02.835618Z 0 [Note] [MY-012487] [InnoDB] DDL log recovery : begin
2020-08-06T14:25:02.936146Z 0 [Warning] [MY-010068] [Server] CA certificate /var/mysql/sslinfo/cacert.pem is self signed.
2020-08-06T14:25:02.963127Z 0 [Note] [MY-010253] [Server] IPv6 is available.
2020-08-06T14:25:03.109022Z 5 [Note] [MY-010051] [Server] Event Scheduler: scheduler thread started with id 5

默认的日志格式:

time thread [label] [err_code] [subsystem] msg

[] 方括号字符是消息格式中的文本字符。它们不表示字段是可选的。

错误日志格式化官方文档:dev.mysql.com/doc/refman/...

查看错误日志所在位置

sql 复制代码
 show variables like "%log_error%";

2.GeneralQuery Log

普通查询日志:通用查询日志是MySQL服务器的一种详细日志,它记录了服务器的所有活动。每当有客户端连接或断开连接时,服务器都会把这些信息写入到通用查询日志中。此外,客户端发送给MySQL服务器的每一条SQL语句,无论是查询、更新还是其他操作,都会被记录在这个日志中。

概览:

sql 复制代码
2023-11-13T03:46:23.001162Z 187936 Query  SELECT 1
2023-11-13T03:46:23.002168Z 187936 Query  SET autocommit=0
2023-11-13T03:46:23.002983Z 187936 Query  select * from xxl_job_lock where lock_name = 'schedule_lock' for update

这个日志会记录所有的查询,因此体积会非常的大,但是默认情况下GeneralQuery Log是关闭的,所以不会有什么影响,如果你需要排查查询相关问题的话,这个日志可能会对你有所帮助。

开启普通查询日志的方法

ini 复制代码
# 开启
SET GLOBAL general_log = 'ON';
# 关闭
SET GLOBAL general_log = 'OFF';
# 查询日志位置
show variables like '%general_log%';

3.Slow Query Log

慢查询日志:用于记录慢查询的日志,当你有慢查询产生时,如果开启了这个功能就会去记录慢查询日志,清晰的告诉你,什么时间、什么库、什么sql、的慢查询信息。

查询是否开启慢查询日志

vbnet 复制代码
# 查询慢查询日志是否开启,返回的第一列如果是ON则代表开启,OFF则关闭,无数据也是关闭
show variables like '%slow_query_log%';

开启慢查询日志

ini 复制代码
# 开启
SET GLOBAL slow_query_log = 'ON';
# 关闭
SET GLOBAL slow_query_log = 'OFF';

设置慢查询时间

用于配置SQL运行耗时大于多少秒才记录这个SQL。

sql 复制代码
# 设置如果sql超过了10秒,才记录这个sql为慢查询sql
SET GLOBAL long_query_time = 10;
# 验证是否更改成功,如果返回了你设置的时间,则代表设置成功
show global variables like '%long_query_time%';

慢查询日志概览

css 复制代码
root@sss-mysql:/var/lib/mysql# cat /var/lib/mysql/sss-mysql-slow.log
/usr/sbin/mysqld, Version: 8.0.27 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
# Time: 2023-11-13T04:23:19.312891Z
# User@Host: root[root] @  [192.168.40.178]  Id: 188030
# Query_time: 1347.713874  Lock_time: 0.000673 Rows_sent: 1  Rows_examined: 34668
use sss;
SET timestamp=1699848051;
select count(c.id),sum(a.account_json),avg(a.id) FROM account_info a 
inner join account_info b on a.id = b.id or a.account_json = b.account_json
inner join order_download_range c on a.id = c.id or a.id = c.deleted
inner join order_download_range d on a.id = d.id or a.id = c.deleted
inner join order_download_range e on a.id = e.id or a.id = c.deleted
where a.account_json like '%1%' or b.account_json like '%1%' and c.params like '%a%';

4.Binary Log

二进制日志: 通常被称为binlog,其中包含描述数据库更改的"事件",例如表创建操作或表数据更改。它还包含可能已进行更改的语句的事件(例如, DELETE没有匹配任何行),除非使用基于行的日志记录。二进制日志还包含有关每个语句更新数据所需时间的信息。二进制日志有两个重要用途:

  • 对于复制,复制源服务器上的二进制日志提供要发送到副本的数据更改的记录。源将其二进制日志中包含的信息发送到其副本,副本复制这些事务以进行与源上所做的相同的数据更改。
  • 某些数据恢复操作需要使用二进制日志。恢复备份后,将重新执行备份后记录在二进制日志中的事件。这些事件使数据库从备份时起保持最新状态。

二进制日志不记录SELECT、SHOW语句 ,如果需要查看这些语句,你应该使用普通查询日志来查看。

通常binlog用于数据的同步,MySQL的主从复制,数据恢复等场景。


5.Undo Log

仅支持InnoDB引擎

回滚日志:


6.Redo Log

什么是redolog?

redolog译为重做日志: 是一种基于磁盘数据结构的日志,在崩溃恢复期间用于纠正不完整事务写入的数据。用于MySQL宕机后的数据恢复。

redolog为什么可以保证数据不丢失?

通俗的来讲就是,MySQL在收到数据变更请求时(Update、Delete、Insert),会先记录一条日志日志中包含本次变更所需的各种参数,如果事务提交了但是MySQL宕机了,在MySQL再次重启的时候MySQL会去检查这个日志文件,发现你有一条数据有记录但是未更新成功,MySQL就会将这条记录刷新到磁盘,从而保证数据不会丢失。

redolog产生的时机

在事务提交之前MySQL会先写一条redolog日志,日志会记录下对磁盘中某某页,某某位置的修改记录,这个操作是顺序IO因此性能很好,每次事务前都会产生一条redolog。

增加了redolog机制为什么速度依然很快?

redolog也采用了缓冲池的概念,新产生的redolog并不会直接写入到磁盘中去,而是先在内存中进行存储,因为内存的速度要比磁盘快很多,在结合MySQL中的异步刷盘机制,完成redolog日志刷盘,刷盘的时机如下:

  • 每秒1次
  • 事务提交时
  • redo log缓冲池空间小于一半时。

缓冲池 buffer pool

MySQL在存储数据的时候是随机存储的,因为不能保证被更改每个数据的位置顺序的,因此会产生大量的随机读写IO的操作,我们指定随机的性能都是非常差的,即使你使用的是SSD,那么MySQL中就衍生出了一个缓冲池的功能,它会现将需要变更的数据写到缓存池内,缓冲池是一片内存空间,因此效率非常高,然后会异步的将数据随机写入到磁盘里,完成数据的落盘操作。也是因此InnoDB的性能才会这么的高。

redolog的checkpoint_lsn

如果发生数据变更MySQL会将数据写入到redolog中,再由异步线程将redolog中的数据写入到磁盘,而checkpoint_lsn就起到了告诉MySQL要从哪里开始刷数据了,redolog文件中会记录当前事务对应的LSN(Log Sequence Number),MySQL会记录当前刷新到的LSN,然后去不断的刷新大于自己的LSN序列化对应的redolog日志。

崩溃恢复也是一样的道理,MySQL重启时会检查redolog文件中是否有大于自己的LSN,如果有的话就根据规则将数据落库,实现崩溃恢复数据不丢失的效果。

问题来了,MySQL是怎么保证日志一定是存在的呢?

MySQL为了解决这个问题,就使用了WAL(Write-Ahead Logging)日志先行的机制:在事务提交之前MySQL会先写一条redolog日志,只有redolog刷盘成功了,这个事务才代表成功。否则就会触发回滚。

redolog详细流程

假设我们现在执行了一次update:begin;update users set name='张三' where id=1;commit;,innoDB的流程如下:

  • MySQL服务器收到指令后会生成一个全局的事务id,这个id会贯穿在binlog和redolog中

  • 去缓冲池中查找id=1的数据,如果没有就去磁盘找,并加载到缓冲池。

  • 修改缓冲池中id=1的数据。

  • 记录数据到redolog buffer和binlog cache

    • 根据redolog刷盘策略,数据很可能会被刷新到磁盘
  • 服务器收到commit指令。

  • 刷新redolog buffer到磁盘(保证redolog一定能刷到磁盘),并标记事务状态为prepare准备状态。

  • 刷新binlog cache到磁盘

  • 刷新redolog buffer到磁盘(保证redolog一定能刷到磁盘),并标记事务状态为commit提交。

  • 返回事务结果

这种先标记为准备状态,在刷新binlog,在标记为提交状态称为二段式提交,也称为内部XA事务。


7.RedoLog插曲

1.为什么有了binlog还需要redolog

binlog不知道数据是哪个时刻出现了丢失。

2.为什么有了redolog还需要binlog

binlog是服务器层面的功能,并非InnoDB独享,而redolog是InnoDB独有的功能。

binlog和redolog都有很多的好处,MySQL设计时考虑到了多种不同的应用场景,因此设计成了两种日志,只能说两种功能互补。

相关推荐
Rust研习社17 分钟前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
IT_陈寒41 分钟前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro1 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax2 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH2 小时前
Koa和Express的区别
后端
MariaH2 小时前
Koa框架的使用
后端
luckdewei3 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某4 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy5 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom5 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github