MySQL日志可以用来干啥?
MySQL日志可以用来干啥?
xiaoyan了解MySQL的童靴们都知道,MySQL有好几种日志——undo log(回滚日志)
、redo log(重做日志)
还有binlog(归档日志)
,为啥需要这么多日志?这些日志分别都是干啥用的?在进一步探讨这么些问题之前,我们需要先了解一下一条SQL语句的执行过程。
笔者作为一名初学小白,时常感到好奇:当执行了 SQL 语句对数据记录进行修改时,如果突然遭遇系统关机、服务器卡死等故障,这段记录修改该如何是好?
小伙伴们可能会不假思索地回答:“通过事务回滚恢复到执行增删改之前的状态!” 没错,这确实是 MySQL 保障数据安全的重要机制之一。即使我们没有显式地开启事务和提交事务,MySQL 也会隐式地启动事务执行“增删改”语句,并在执行完后自动提交事务(MySQL 默认开启了 autocommit
参数)。
但你是否想过,MySQL 是如何实现这种“时光倒流”般的神奇操作的呢?这就要归功于 MySQL 的“时光机”—— undolog、redolog 和 binlog。它们就像数据库的“守护天使”,默默地记录着数据的每一次变化,在关键时刻挺身而出,保障数据的安全性和一致性。
undolog、redolog 和 binlog 是 MySQL 保障数据安全的三大利器,它们各司其职,共同构建了 MySQL 强大的数据保护机制:
- undolog :负责事务的原子性和 MVCC,确保数据的一致性。
- redolog :负责事务的持久性,确保数据不会因故障而丢失。
- binlog :负责数据的备份和主从复制,确保数据的可靠性和高可用性。
接下来,我们来进一步探讨这三种日志如何实现数据库神操作。
Undo Log 是干啥的
在前言我们提到,MySQL 会隐式开启事务执行“增删改”语句,当操作过程中发生崩溃时,事务会进行回滚。那么,回滚操作中旧的数据要从哪里来呢?
想象一下,如果在执行“增删改”操作之前,我们将要操作的数据记录做一个备份,那么当我们想恢复到执行操作之前的状态时,只要对照备份的信息就可以了。
当然,每次执行操作都要进行备份会很麻烦,但我们可以根据需求进行相应的操作记录。例如:
- 执行删除操作之前,记录要删除的记录信息,若想恢复,我们再把记录插回去;
- 执行新增操作之前,记下新增记录的ID,撤销新增只需要把对应ID记录删除即可;
- 执行修改操作之前,记录修改前的数据,撤销修改时只需将数据恢复到修改前的状态。
这种记录操作前数据的方式,正是 MySQL 中 Undo Log (回滚日志)的核心思想。Undo Log 记录了事务执行过程中对数据的修改操作,用于在事务回滚时撤销这些修改,将数据恢复到事务开始前的状态,它保证了事务的ACID特性中的原子性。
undo log 是一种用于撤销回退的日志。在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日
志文件里面,当事务回滚时,可以利用 undo log 来进行回滚。如下图:
每当 InnoD8 引擎对一条记录进行操作(修改、删除、新增)时,要把回滚时需要的信息都记录到 undo log 里,发生回滚时,就读取undo log日志记录的数据,执行相反的操作来完成数据恢复。
需要注意的是,不同的操作,因需求不同,其undo log格式也不同,此处仅以更新操作的日志为例。每条记录的每一次更新操作产生的 Undo Log 格式中,都包含一个 roll_pointer
指针和一个 trx_id
事务 ID:
trx_id
事务 ID:用于标识该记录是被哪个事务修改的,帮助系统追踪事务的执行顺序。roll_pointer
指针:将这些 Undo Log 串成一个链表,这个链表就被称为版本链。版本链记录了该记录的所有历史版本,使得系统可以在需要时回滚到任意一个历史状态。
版本链的结构如下图所示:
另外,Undo Log 通过 ReadView + Undo Log 实现 MVCC(多版本并发控制)。
对于「读提交」和「可重复读」隔离级别的事务:
- 「读提交」:每次
SELECT
生成新的 Read View,可能导致同一事务中多次读取同一条数据时结果不一致。 - 「可重复读」:事务启动时生成 Read View,并在整个事务期间使用,确保读取的数据一致。
这两个隔离级别通过「事务的 Read View 里的字段」和「记录中的隐藏列(trx_id
和 roll_pointer
)」进行比对,如果不满足可见性条件,就会顺着 Undo Log 版本链找到满足其可见性的记录,实现 MVCC。
因此,Undo Log 的两大作用是:
- 实现事务回滚,保障事务的原子性:在事务处理过程中,如果出现错误或用户执行
ROLLBACK
语句,MySQL 可以利用 Undo Log 中的历史数据将数据恢复到事务开始之前的状态。 - 实现 MVCC(多版本并发控制)的关键因素之一:MVCC 通过 ReadView + Undo Log 实现。Undo Log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通
SELECT
语句)时,会根据事务的 Read View 里的信息,顺着 Undo Log 的版本链找到满足其可见性的记录。
Buffer Poll是干啥的
【更新中。。。】