【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设计时考虑到了多种不同的应用场景,因此设计成了两种日志,只能说两种功能互补。

相关推荐
程序猿进阶2 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺7 分钟前
Spring Boot框架Starter组件整理
java·spring boot·后端
凡人的AI工具箱29 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
先天牛马圣体34 分钟前
如何提升大型AI模型的智能水平
后端
java亮小白199737 分钟前
Spring循环依赖如何解决的?
java·后端·spring
2301_811274311 小时前
大数据基于Spring Boot的化妆品推荐系统的设计与实现
大数据·spring boot·后端
草莓base2 小时前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Ljw...2 小时前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改
编程重生之路2 小时前
Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常
java·spring boot·后端
薯条不要番茄酱2 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea