MySQL之重做日志

198 阅读3分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。

一、有什么作用?

  1. 为了保证事务提交后数据的正确性。
  2. 解决了插入、更新数据时随机访问磁盘速度慢的问题。

二、WAL技术

当执行插入或更新操作时,数据先被写入 redo log,然后 InnoDB 引擎在合适的时候会把数据写入磁盘(数据页)。

注意点

  1. 写入 redo log 是顺序写入的,即使机械硬盘速度也很快。
  2. redo log 分为 redo log buffer 和 redo log file,数据什么时候从 buffer 刷到 file 中是可以配置的。

由此产生了一个名词 Write-Ahead-Log(WAL) 即:先写日志再写数据。

举例:菜馆老板记账的故事。

客人来赊账,老板先把赊账记录临时记录到一个小本本(redo log)上,等到不忙的时候再把小本本上的记录整理到总账本上,不然每个人来赊账的时候都要去查找总账本,找这个人的赊账记录,进行新增修改或删除,效率比较低。

三、LSN

LSN(log sequence number):日志序列号,是一个一直递增的整形数字,在 MySQL5.6.3 版本后占8个字节。它表示事务写入到日志的字节总量。LSN主要用于发生 crash 时对数据进行 recovery !每个数据页、重做日志、checkpoint都有LSN。

使用 show engine innodb status\G 可以看到日志中 lsn 的信息,如下:

---
LOG
---
Log sequence number 433500797
Log flushed up to   433500797
Pages flushed up to 433500797
Last checkpoint at  433500788
0 pending log flushes, 0 pending chkp writes
289 log i/o's done, 0.00 log i/o's/second
属性说明
Log sequence number当前系统最大的LSN号
log flushed up to当前已经写入redo日志文件的LSN
pages flushed up to已经将更改写入脏页的LSN号
Last checkpoint at系统最后一次刷新buffer pool脏中页数据到磁盘的checkpoint

四、checkpoint

6F4285F2-F3A0-43B8-8BAC-D0ED89A96BA7

write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。

checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

write pos 和 checkpoint 之间的是“粉板”上还空着的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。

五、配置参数

1、innodb_flush_log_at_trx_commit

作用:控制 redo log 刷盘策略,将 redo log buffer 刷到 redo log file 中。

取值范围 0,1,2:

  • 值为 0 时:日志每秒被写入和刷新到磁盘。
  • 值为 1 时:默认值,每次事务提交时后会写入日志并刷盘。
  • 值为 2 时:在每次事务提交后写入日志,并每秒刷新一次磁盘。

47BBB576-3C28-44A7-B0B0-CCBB1E907393

2、innodb_log_buffer_size

缓冲的大小,配置的值越大,就可以避免大事务在事务提交前将日志写入磁盘。

  • 默认值:16777216(16M)
  • 最小值:1048576(1M)
  • 最大值:4294967295(4G)

3、innodb_log_file_size

控制每个 redo log 文件的大小。

默认值可以设置为 1G。

4、innodb_log_files_in_group

设置在一个组内可以有多少个重做日志文件。

  • 默认值:2 个
  • 最小值:2 个
  • 最大值:100 个

注意:innodb_log_file_size * innodb_log_files_in_group < 512G。

5、innodb_log_group_home_dir

设置 redo log file 的目录。默认在 datadir 目录下。