MySQL 的事务日志(Transaction Log)记录了数据库系统执行过的所有修改操作,以便数据库在突然停机等异常情况下能够恢复到某个稳定的状态。事务日志分为两类:redo log 和 undo log。
1. Redo Log
redo log 是在事务提交之前,将新数据修改的记录先写到 redo log 中,然后在将数据修改反映到磁盘上。redo log 是顺序写入的,使用 Format Description Event (FDE) 格式存储事务元数据。可以通过以下命令查看当前重做日志文件:
SHOW VARIABLES LIKE 'innodb_log_file_size';
其中 `innodb_log_file_size` 表示 redo log 文件大小,一般情况下默认值为 48MB,因为这是写入数据之前每个事务都要执行的操作,如果过小,则必须频繁地创建新的日志文件。
redo log 的主要流程:
1. 事务修改数据库时,将 redo log 记录到内存中的链表(redo log buffer)中。
2. 当 redo log buffer 满或者事务提交时,将 redo log 记录归档到文件系统中的 redo log 文件中。
3. 系统汇总多个事务的 redo log 文件,写到磁盘的内存中。
4. 定期将内存中的 redo log 写入磁盘,形成归档日志。
2. Undo Log
undo log 记录了事务执行的所有操作,因此可以用于事务回滚(rollback)和 MVCC 特性的实现。undo log 也是顺序写入的,以 extents(每个 extent 存储 1GB 的 512B 数据块)为单位写入磁盘。每个 undo log 记录都有一个指针,指向其下一个 undo log。
undo log 的主要流程:
1. 在事务修改数据之前,将原数据备份到 undo log 中。
2. 事务提交后,删除保存在 undo log 中的数据。
3. 事务日志文件格式
事务日志文件的存储格式是由 3 部分组成:
1. 头部信息,包括文件头、重做日志块开头、结尾的日志标识等。
2. 日志块(log block),由多个日志记录(log record)组成。
3. 尾部信息,重做日志的校验和。
事务日志记录主要包括三个部分:
1. 事务 ID(Transaction ID),标记一个事务的唯一性,通过这个事务 ID,可以将一个事务的所有日志记录串联起来,还可以追踪与该事务相关的所有操作。
2. 日志种类(Log Type),表示该记录是什么类型的日志。
3. 日志内容(Log Data),记录了这个操作。其中,事务开始、提交、回滚等操作又被称为重做日志(redo log)。
4. 事务日志的应用场景
事务日志的主要应用场景包括:
1. 崩溃恢复(Crash Recovery):当数据库意外崩溃时,可以通过事务日志回复到数据库崩溃前的状态。
2. 主从同步(Replication):主库通过将 redo log 同步到从库,从库按照主库执行一遍 SQL,完成主从同步。
3. 读写分离(Read-write Separation):通过从库的 redo log 生成快照,提供给读请求,实现读写分离。