日志
Mysql有三大日志系统
-
Undo Log(回滚日志):记录修改前的数据,用于事务回滚和 MVCC(多版本并发控制)。
-
Redo Log(重做日志):记录数据变更,用于崩溃恢复,确保持久性。
-
Binlog(备份日志):记录事务操作日志,用于主从复制和灾难恢复。
Redo Log
Redo Log 记录的是物理日志,也就是磁盘数据页的修改(Redo Log 记录了哪些数据被修改,以及修改前后的数据内容。包括被修改的数据页或块的位置信息)
作用:用来保证服务崩溃后,仍能把事务中变更的数据持久化到磁盘上
背景:当数据库对数据做修改时,需要把数据页从磁盘读到buffer pool中,然后在buffer pool中进行修改,那么这个时候buffer pool中的数据页就与磁盘上的数据页内容不一致,称buffer pool的数据页为脏数据,如果这个时候发生非正常的DB服务重启,那么这些数据还在内存,并没有同步到磁盘上,也就是发生数据丢失,那么这个时候使用redo log,在buffer pool的数据页变更结束后,就可以相应修改记录到这个文件,那么当DB服务发生崩溃宕机时,进行恢复DB时,可以根据文件的记录内容,重新持久化刷新到磁盘数据(redo log ,用于记录数据修改后的记录,顺序记录,主要用于数据的持久化操作。)、
组成:
-
redo log buffer日志缓存
重做日志缓存存在于内存中,容易发生丢失,先缓存数据,再一次性存入磁盘。
-
redo log file日志文件
存在于磁盘中,不容易发生丢失
redo log buffer是在内存中的,写入buffer后,并不会立即持久化到Redo log file,需要等待操作系统调用fsync操作(具体什么时候使用innodb_flush_log_at_trx_commit 参数配置)
参数值 | 含义 |
---|---|
0(延迟写) | 提交事务后,不会立即刷到OS Buffer中,而是等一秒后刷新到OS Buffer并调用fsync()写入Redo Log FIle,可能会丢失一秒钟的数据。 |
1(实时写 | 每次提交事务,都会刷新到OS Buffer并调用fsync()写到Redo Log FIle,性能较差 |
2(延迟刷新) | 每次提交事务只刷新到OS Buffer,一秒后再调用fsync()写入Redo Log FIle。 |
Undo Log
Undo Log回滚日志记录的是逻辑日志,也就是sql语句(比如当我们执行一条insert语句,Undo Log记录一条相反的delete语句--但它并不是简单地存储原始的SQL语句,而是存储相应的逆操作及相关的数据状态。这种设计使得回滚操作更直接和高效。)
作用:
-
回滚事务:当事务需要回滚时,数据库系统使用Undo Log来撤销事务已经执行的修改,恢复到事务开始之前的数据状态。
-
MVCC多版本控制:Undo Log在实现多版本并发控制(MVCC)中也起到关键作用。通过记录数据的历史版本,系统可以提供一致的读视图,支持并发事务的读取和修改。
组成:也是有undo buffer和undo logo日志组成
原理:如我们执行下面一条删除语句:
delete from user where id = 1;
那么此时undo log就会记录一条对应的insert语句(反向),以保证事务回滚时,将数据还原回去。
Undo log存储由InnoDB的存储引擎实现,数据保存再innoDB的数据文件中,再存储引擎中,undo log是采用分段的方式进行存储的。rollback segment称为回滚段。在MySQL5.5之后,可以支持128个rollback segment,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成,即总共可以记录128 * 1024个undo操作。
undo log日志存放的信息如下
-
undo log日志里面不仅存放着数据更新前的记录,还记录着RowID、事务ID、回滚指针,其中事务ID每次递增,回滚指针第一次如果是insert语句的话,回滚指针为null,第二次update之后undo log的回滚指针就会指向刚刚那一条undo log日志,以此类推形成了一条undo log的回滚链,便于找到该记录的历史版本
-
在事务提交之前会将数据备份到undo buffer,然后由undo buffer持久化到磁盘中的undo log文件中,此时undo log保存了之前未提交之前的操作日志,接着将操作的数据,持久化到数据文件中(更新数据前记录undo log)
例如:假设有A、B两个数据,值分别为1,2。
A. 事务开始
B. 记录A=1到undo log中
C. 修改A=3
D. 记录B=2到undo log中
E. 修改B=4
F. 将undo log写到磁盘 -------undo log持久化
G. 将数据写到磁盘 -------数据持久化
H. 事务提交 -------提交事务
Bin Log
Binlog 是 MySQL 中用于记录数据库修改操作的日志文件。binlog记录的是逻辑日志,即原始的sql语句,是mysql自带的。是mysql数据库中的二进制日志文件,用于记录数据库的所有更改操作。他以二进制的形式存储,包含了对数据库执行所有修改操作的详细信息,如插入、更新、删除等。BInlog是Mysql事务日志的一部分,与Redo log一起,确保数据库的一致性,持久性,以及提供一些关键的数据库管理功能。
作用
用于数据备份、主从同步、数据恢复
-
主从复制:在主从复制中,主服务器将所有的更改记录到Binlog中,而从服务器通过读取主服务器的Binlog并执行相同的更改来保持数据同步。这实现了数据的复制和冗余,提高了系统的可用性和可靠性。
-
数据库备份:Binlog也是数据库备份的一部分。通过备份Binlog,可以实现增量备份,只备份自上次完整备份以来发生的变更,从而减少备份的时间和存储成本。
-
数据恢复:在数据库崩溃或数据丢失时,可以使用 Binlog 进行数据恢复。通过重放 Binlog 中记录的所有操作,可以将数据库恢复到某个特定时间点。
组成
事件头(Event Header):
-
包含事件的时间戳、类型、服务器ID等信息。
事件数据(Event Data):
-
具体记录了对数据库表的修改操作。根据事件类型不同,事件数据也有所不同,比如可能是表结构变更、行数据修改等。
文件格式描述符(File Format Descriptor):
-
描述了 Binlog 文件的格式信息,通常在 Binlog 文件的开头。
Binlog 的类型
MySQL 的 Binlog 有三种格式:
-
STATEMENT(语句模式):
-
记录的是执行的 SQL 语句。优点是日志文件较小,缺点是某些非确定性的操作可能导致复制不一致。
-
记录原始SQL语句,会导致更新时间与原库不一致。 比如 update_time=now()
-
-
ROW(行模式):
-
记录的是每行数据被修改的具体信息。优点是可以确保复制的一致性,缺点是日志文件较大。
-
-
MIXED(混合模式):
-
结合了语句模式和行模式的优点。MySQL 自动选择最合适的格式记录日志。
-
Statement和Row的混合模式,默认采用Statement模式,涉及日期、函数相关的时候采用Row模式,既减少了数据量,又保证了数据一致性。
这时,MySQL并不会立即刷盘,而是依据
sync_binlog
参数决定刷盘的频率和时机。参数值 含义 0(延迟写) 每次提交事务都不会刷盘,由系统自己决定什么时候刷盘,可能会丢失数据。 1(实时写) 每次提交事务,都会刷盘,性能较差。 N(延迟写) 提交N个事务后,才会刷盘。 -
事务提交前刷盘过程
事务开始:
-
执行一组数据库操作,如插入、更新、删除等。
写入 Undo Log 缓冲区:
-
在执行修改操作之前,首先将修改前的记录写入 Undo Log 缓冲区。这一步骤确保了即使在事务失败或回滚时,可以恢复到修改前的状态。
写入Redo Log缓冲区:
-
同时,修改操作的Redo Log记录也写入内存中的Redo Log缓冲区。
写入 Binlog 缓冲区:
-
在执行这些操作的过程中,MySQL 会将这些操作记录在 Binlog 缓冲区中。
准备提交:
-
当事务准备提交时,MySQL 会将 Binlog 缓冲区的内容写入磁盘上的 Binlog 文件。这一步是为了确保即使在事务提交之后发生系统崩溃,事务的操作记录仍然可以从 Binlog 中恢复。
-
当事务准备提交时,MySQL会将Binlog缓冲区的内容写入到磁盘上的Binlog文件中。
这时,MySQL并不会立即刷盘,而是依据
sync_binlog
参数决定刷盘的频率和时机。
写入 Redo Log:
-
将事务的变更记录写入到 InnoDB 的 Redo Log 中。这也是在事务提交之前进行的,以确保数据的持久性。
-
根据
innodb_flush_log_at_trx_commit
参数的设置,决定是否立即将 Redo Log 刷盘到磁盘。
写入 Undo Log 文件:
-
在事务准备提交时,MySQL 会将 Undo Log 缓冲区的内容写入到磁盘上的 Undo Log 文件中,以确保事务的回滚信息持久化。
然后提交事务