MySQL中的redo log、 undo log、bin log
1. redo log
redo log
(重做日志)是MySQL InnoDB存储引擎中非常重要的一部分,用于保证数据库的持久性和崩溃恢复。它记录了对数据页所做的所有修改操作,确保在系统崩溃或其他意外情况下、数据库可以通过redo log
进行恢复,使数据保持一致。
1.1 redo log的组成
redo log 主要由以下几个部分组成:
redo log buffer: 这是位于内存中的环形缓冲区,用于临时存放即将写入redo log文件的日志。数据先被写入redo log buffer,然后定期刷新到磁盘中的redo log文件中。
redo log files: 这是持久化存储在磁盘上的日志文件,通常由两个或多个文件组成,形成一个环形的日志文件集合。redo log的大小和数量在数据库配置中可以指定。
1.2 redo log的工作原理
redo log是一个典型的WAL(Write-Ahead Logging)日志系统,其工作原理如下:
1.事务执行: 当事务开始执行并对数据库进行修改时,修改的内容会被先写入redo log buffer。
2.写入redo log buffer: 数据的更改操作记录会首先被写入内存中的redo log buffer,而不是直接写入数据文件。这提高了性能,因为内存操作比磁盘I/O操作要快得多。
3.事务提交: 当事务提交时,redo log buffer会被刷新到磁盘中的redo log文件,这个过程称为fsync操作。只有当redo log记录成功持久化后,事务才会被认为是提交成功的。
4.数据文件更新: 后台进程(如InnoDB的checkpoint进程)会定期将缓存在内存中的数据页刷新到磁盘的数据文件中,这个过程是异步的。即使在事务提交时数据文件未更新,只要redo log中有记录,数据的修改就不会丢失。
5.崩溃恢复: 如果MySQL发生崩溃,在重启时,InnoDB存储引擎会通过redo log来恢复未提交的事务。它会读取redo log中的记录,并将这些记录重新应用到数据文件上,确保数据库的完整性和一致性。
1.3 redo log的作用
redo log的主要作用如下:
1. 持久性保障: 即使系统崩溃,redo log也可以帮助恢复数据到一个一致的状态,确保事务的持久性(Durability),即ACID特性中的D。
2. 崩溃恢复: 在数据库意外宕机或崩溃后,重启时InnoDB通过redo log恢复未完成的事务,确保数据一致性。
3. 性能优化: 通过先写redo log再刷写数据文件,减少了频繁的随机写操作,转换为顺序写操作,极大地提高了写入性能。
1.4 redo log的工作机制
1. 日志序列号(Log Sequence Number,LSN)
redo log中的每一个日志记录都有一个唯一的日志序列号(LSN),用于标识日志的顺序。InnoDB使用LSN来跟踪日志写入的进度以及数据库的恢复进度。
checkpoint LSN:表示已经将redo log中的更改应用到数据文件中的位置。checkpoint的推进会清理旧的redo log,避免日志文件过大。
2. 环形日志文件
redo log文件集是一个固定大小的环形缓冲区。当日志写到文件末尾时,会回到文件的开头继续写入(覆盖旧的日志)。为了确保覆盖旧日志前,旧日志所对应的修改已经被刷新到数据文件中,InnoDB通过checkpoint机制来管理redo log的写入和回收。
3. checkpoint机制
checkpoint使InnoDB用于管理redo log文件的机制,主要功能包括:
数据持久化: 将内存中的脏页刷新到数据文件中,确保再redo log文件被覆盖之前,这些修改已经持久化到数据文件中。
redo log文件回收: 当checkpoint向前推进时,旧的redo log可以被覆盖,从而循环使用redo log文件,避免文件无限增长。
1.5 redo log与binlog的区别
在MySQL中,redo log和binlog是两种不同的日志,虽然它们在某些方面存在关联,但它们有不同的用途和功能:
用途:
redo log:用于崩溃恢复和保障事务的持久性,是InnoDB存储引擎的一部分。
binlog:用于记录所有对数据库进行更改的SQL语句(包括非InnoDB存储引擎),支持数据库的恢复、复制和审计。
存储层级:
redo log:位于存储引擎层(InnoDB),只记录物理日志(即数据页的变更)。
binlog:位于MySQL Server层,记录的是逻辑日志(即SQL语句)。
写入时机:
redo log:事务提交时会立即写入,以保障崩溃恢复。
binlog:事务提交时才写入,并且在redo log提交后写入。
2. undo log
undo log(回滚日志)是MySQL InnoDB存储引擎中用于实现事务回滚和多版本并发控制(MVCC)的关键组件。undo log记录了数据被修改之前的状态,以便在需要时能够将数据回滚到原始状态。它还用于提供一致性读,以支持事务隔离级别。
2.1 undo log的作用
undo log的主要作用有两个:
1.事务回滚: 当一个事务执行了某些更新操作后,如果该事务因某种原因(如用户主动回滚或异常发生)需要回滚,undo log可以将数据恢复到修改前的状态。
2. 多版本并发控制(MVCC): undo log为每个事务提供了一个数据的历史版本。通过这些历史版本,不同事务在不同的时间点可以看到相同数据的不同版本,从而实现非阻塞的读操作,保证一致性读。
2.2 undo log的类型
undo log主要有两种类型:
1. 插入undo日志(Insert Undo Log):
记录由INSERT语句产生的新行数据。当事务回滚时,这些新插入的行数据会被删除。
插入undo log在事务提交后可以被立即删除,因为提交后不会再被使用。
2.更新undo日志(Update Undo Log):
记录由UPDATE或DELETE语句导致的行数据的旧版本。用于支持回滚操作,以及在事务未提交前提供历史版本以支持一致性读。
更新undo log在事务提交后不能立即删除,因为它可能会被其他事务用于一致性读。
2.3 undo log的工作原理
1. 生成undo log: 当一个事务对数据进行修改时,InnoDB会首先生成undo log,记录数据在修改前的原始状态。
对于INSERT操作,undo log记录的是插入的新数据行。
对于UPDATE和DELETE操作,undo log记录的是被修改或删除的数据行的旧版本。
2. 事务操作: 事务继续执行,并在内存中对数据页进行修改。此时,undo log为这些数据的旧版本提供了一种回滚机制。
3.事务回滚: 如果事务需要回滚,InnoDB会通过读取undo log中的记录,将数据恢复到修改前的状态。
4.事务提交: 当事务提交时,插入类型的undo log会被立即清除,而更新类型的undo log会暂时保留,以支持其他事务的一致性读。
5. 一致性读: 对于某些隔离级别,如REPEATABLE READ,事务在执行查询时,会根据undo log创建数据的历史版本,从而实现一致性读。历史版本的创建依赖于更新类型的undo log。
2.4 undo log与MVCC
多版本并发控制(MVCC)是InnoDB的一个重要机制,依赖于undo log提供的历史版本来实现。在REPEATABLE READ隔离级别下,MVCC的工作原理如下:
读取旧版本: 当一个事务读取某条记录时,如果另一事务已经对该记录进行了更新但未提交,InnoDB会根据undo log中的信息生成该记录的旧版本,并返回给当前事务。
事务隔离: 通过undo log生成的数据版本,使得每个事务在进行查询时,能看到其启动时的数据快照,避免了“脏读”和“不可重复读”的问题。
版本链: 每条记录可以对应多个历史版本,这些版本通过undo log串联成一个版本链,形成一个多版本的数据快照供并发事务访问。
2.5 undo log的存储与管理
存储位置
undo log存储在InnoDB表空间中。默认情况下,undo log存储在共享表空间中,但也可以配置为存储在单独的撤销表空间中,以便更好地管理和优化。
清理与回收
InnoDB会定期对已经提交的事务的undo log进行清理。这种清理过程称为purge。对于已经提交并且不再需要的undo log,InnoDB会将其标记为可回收,并最终删除或重用这些空间。
性能影响
尽管undo log在事务隔离和数据恢复中至关重要,但大量未清理的undo log可能会导致表空间膨胀,影响性能。因此,适时清理undo log对数据库性能的维护至关重要。
2.6 undo log与redo log的区别
尽管undo log和redo log都是MySQL InnoDB存储引擎中的关键日志机制,但它们的作用和工作方式不同:
作用:
undo log:用于事务回滚和MVCC,记录的是数据的旧版本。
redo log:用于崩溃恢复,记录的是数据修改操作,确保数据修改的持久性。
写入时机:
undo log:在事务修改数据之前生成,记录数据修改前的状态。
redo log:在事务提交时写入,记录数据修改后的状态。
日志内容:
undo log:记录的是逻辑日志,即修改前的数据内容,用于回滚和生成历史版本。
redo log:记录的是物理日志,即数据页的修改操作,用于崩溃后的数据恢复。
3. bin log
binlog(二进制日志)是MySQL数据库系统中非常重要的日志文件,用于记录对数据库执行的所有修改操作。binlog不仅在数据恢复中起重要作用,还支持MySQL的主从复制和审计功能。理解binlog的作用和工作原理对于数据库管理、数据恢复、以及性能优化都至关重要
3.1 binlog的作用
数据恢复: binlog记录了所有修改数据的操作(如INSERT、UPDATE、DELETE等)。如果数据库发生崩溃或数据丢失,可以通过重放binlog来恢复数据。
主从复制: MySQL的主从复制机制依赖于binlog。主服务器上的binlog记录会被复制到从服务器上,从服务器根据binlog的内容重放这些操作,从而保持与主服务器数据的一致性。
审计和分析: binlog中详细记录了数据库的修改操作,可以用来审计和分析数据变更。
3.2 binlog的组成
二进制日志文件(binlog files): 这是存储在磁盘上的日志文件,记录了所有数据更改的二进制格式的事件。binlog文件通常按照一定的大小进行滚动,每当一个文件达到指定大小时,会生成一个新的binlog文件。
二进制日志索引文件(index file): 这个文件记录了当前所有binlog文件的列表及其顺序,MySQL通过索引文件来管理和访问多个binlog文件。
3.3 binlog的记录格式
Statement Format(基于语句的复制,SBR):
binlog记录的是执行的SQL语句。主服务器执行的每条SQL语句都会记录到binlog中。
优点:日志量较小,节省存储空间。
缺点:某些不确定性操作(如NOW()、UUID()等)可能会导致复制不一致。
Row Format(基于行的复制,RBR):
binlog记录的是每一行的实际数据变更,而不是SQL语句。即记录的是具体哪一行的哪一列发生了什么变化。
优点:避免了语句执行的副作用,复制更加精确,适合高并发和复杂的事务。
缺点:日志量较大,占用较多的存储空间。
Mixed Format(混合模式,MBR):
混合了基于语句的日志和基于行的日志。一般情况下使用Statement Format,但在一些特殊情况下(如UUID()、NOW()等)自动切换为Row Format。
优点:兼具两者的优点,在保证精确复制的同时节省了存储空间。
缺点:实现较为复杂,可能增加一些性能开销。
3.4 binlog的工作机制
1.SQL语句执行: 当客户端发送一条修改数据的SQL语句时,MySQL会解析和执行该语句。
2.生成事件: 在执行过程中,MySQL将这条SQL语句或相应的行变更操作记录为一个事件,并将该事件写入到binlog cache中。
3.事务提交: 当事务提交时,MySQL会将binlog cache中的事件刷新到磁盘中的binlog文件中。
4.binlog滚动: 当当前binlog文件达到设定的最大大小时,MySQL会生成一个新的binlog文件,继续记录后续的事件。
5.主从复制: 在主从复制环境中,从服务器会读取主服务器的binlog,并根据其中的事件重放这些操作,确保数据与主服务器同步。
3.5 binlog的管理与配置
1. binlog的启用
通过在MySQL配置文件中设置log_bin参数,可以启用binlog。默认情况下,binlog是关闭的,开启后MySQL会开始记录所有的更改操作。
[mysqld]
log_bin = mysql-bin
2. binlog的持久化与清理
binlog文件会占用磁盘空间,因此需要合理配置binlog的清理策略,以避免磁盘空间被大量日志文件占满。
binlog保留策略: 可以通过expire_logs_days参数配置binlog的保留天数,超过设定天数的binlog文件会被自动删除。
expire_logs_days = 7
手动清理: 管理员也可以手动清理不需要的binlog文件,使用PURGE BINARY LOGS命令来删除过期的日志。
PURGE BINARY LOGS TO 'mysql-bin.000010';
或
PURGE BINARY LOGS BEFORE '2024-09-01 00:00:00';
3. binlog的备份与恢复
为了保障数据的安全性,建议定期备份binlog文件。备份的binlog可以用于数据恢复,将其重放到数据库中以恢复到某个时间点或某个事件之后的状态。
备份binlog: 可以简单地复制binlog文件到安全的备份位置。
恢复数据: 通过mysqlbinlog工具,可以将binlog文件中的事件重放到数据库中。
mysqlbinlog mysql-bin.000001 | mysql -u root -p
3.6 binlog与redo log的区别
虽然binlog和redo log都是日志机制,它们的功能和应用场景有所不同:
记录内容:
binlog:记录的是SQL语句或行变更,用于复制和恢复。
redo log:记录的是物理层面的数据页更改,用于崩溃恢复。
持久性:
binlog:位于Server层,服务于全局的复制和恢复。
redo log:位于InnoDB存储引擎层,服务于事务的持久性保障。
应用场景:
binlog:主要用于数据恢复、主从复制、审计和分析。
redo log:主要用于数据库崩溃后的数据恢复。