「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
一、有什么作用?
- 为了保证事务提交后数据的正确性。
- 解决了插入、更新数据时随机访问磁盘速度慢的问题。
二、WAL技术
当执行插入或更新操作时,数据先被写入 redo log,然后 InnoDB 引擎在合适的时候会把数据写入磁盘(数据页)。
注意点:
- 写入 redo log 是顺序写入的,即使机械硬盘速度也很快。
- 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
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 时:在每次事务提交后写入日志,并每秒刷新一次磁盘。
2、innodb_log_buffer_size
缓冲的大小,配置的值越大,就可以避免大事务在事务提交前将日志写入磁盘。
- 默认值:16777216(16M)
- 最小值:1048576(1M)
- 最大值:4294967295(4G)
3、innodb_log_file_size
控制每个 redo log 文件的大小。
- 默认值:50331648(48M)
- 最小值:4194304(4M)
- 最大值:dev.mysql.com/doc/refman/…
默认值可以设置为 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 目录下。