Skip to content

Commit 51aca7a

Browse files
committed
[docs update] MySQL 日志内容完善
1 parent 299f565 commit 51aca7a

File tree

2 files changed

+22
-23
lines changed

2 files changed

+22
-23
lines changed

docs/database/mysql/mysql-logs.md

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,26 @@ tag:
4343

4444
InnoDB 刷新重做日志的时机有几种情况:
4545

46-
1. 事务提交:当事务提交时,相关的重做日志会被刷新到磁盘。这确保了提交的事务对于恢复是可用的。
46+
InnoDB 将 redo log 刷到磁盘上有几种情况:
4747

48-
2. 事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘。
49-
50-
3. Checkpoints(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。
51-
52-
4. 后台刷新线程:InnoDB 启动了一个后台线程,负责周期性地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。
48+
1. 事务提交:当事务提交时,log buffer 里的 redo log 会被刷新到磁盘(可以通过`innodb_flush_log_at_trx_commit`参数控制,后文会提到)。
49+
2. log buffer 空间不足时:log buffer 中缓存的 redo log 已经占满了 log buffer 总容量的大约一半左右,就需要把这些日志刷新到磁盘上。
50+
3. 事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘。
51+
4. Checkpoint(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。
52+
5. 后台刷新线程:InnoDB 启动了一个后台线程,负责周期性(每隔 1 秒)地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。
53+
6. 正常关闭服务器:MySQL 关闭的时候,redo log 都会刷入到磁盘里去。
5354

5455
总之,InnoDB 在多种情况下会刷新重做日志,以保证数据的持久性和一致性
5556

56-
`InnoDB` 存储引擎为 `redo log` 的刷盘策略提供了 `innodb_flush_log_at_trx_commit` 参数,它支持三种策略:
57+
我们要注意设置正确的刷盘策略`innodb_flush_log_at_trx_commit` 。根据 MySQL 配置的刷盘策略的不同,MySQL 宕机之后可能会存在轻微的数据丢失问题。
58+
59+
`innodb_flush_log_at_trx_commit` 的值有 3 种,也就是共有 3 种刷盘策略:
5760

58-
- **0**:设置为 0 的时候,表示每次事务提交时不进行刷盘操作
59-
- **1**:设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值)
60-
- **2**:设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache
61+
- **0**:设置为 0 的时候,表示每次事务提交时不进行刷盘操作。这种方式性能最高,但是也最不安全,因为如果 MySQL 挂了或宕机了,可能会丢失最近 1 秒内的事务。
62+
- **1**:设置为 1 的时候,表示每次事务提交时都将进行刷盘操作。这种方式性能最低,但是也最安全,因为只要事务提交成功,redo log 记录就一定在磁盘里,不会有任何数据丢失。
63+
- **2**:设置为 2 的时候,表示每次事务提交时都只把 log buffer 里的 redo log 内容写入 page cache(文件系统缓存)。page cache 是专门用来缓存文件的,这里被缓存的文件就是 redo log 文件。这种方式的性能和安全性都介于前两者中间。
6164

62-
`innodb_flush_log_at_trx_commit` 参数默认为 1 ,也就是说当事务提交时会调用 `fsync` 对 redo log 进行刷盘
65+
刷盘策略`innodb_flush_log_at_trx_commit` 的默认值为 1,设置为 1 的时候才不会丢失任何数据。为了保证事务的持久性,我们必须将其设置为 1。
6366

6467
另外,`InnoDB` 存储引擎有一个后台线程,每隔`1` 秒,就会把 `redo log buffer` 中的内容写到文件系统缓存(`page cache`),然后调用 `fsync` 刷盘。
6568

@@ -128,11 +131,11 @@ InnoDB 刷新重做日志的时机有几种情况:
128131

129132
注意从 MySQL 8.0.30 开始,日志文件组有了些许变化:
130133

131-
> The innodb_redo_log_capacity variable supersedes the innodb_log_files_in_group and innodb_log_file_size variables, which are deprecated. When the innodb_redo_log_capacity setting is defined, the innodb_log_files_in_group and innodb_log_file_size settings are ignored; otherwise, these settings are used to compute the innodb_redo_log_capacity setting (innodb_log_files_in_group * innodb_log_file_size = innodb_redo_log_capacity). If none of those variables are set, redo log capacity is set to the innodb_redo_log_capacity default value, which is 104857600 bytes (100MB). The maximum redo log capacity is 128GB.
134+
> The innodb_redo_log_capacity variable supersedes the innodb_log_files_in_group and innodb_log_file_size variables, which are deprecated. When the innodb_redo_log_capacity setting is defined, the innodb_log_files_in_group and innodb_log_file_size settings are ignored; otherwise, these settings are used to compute the innodb_redo_log_capacity setting (innodb_log_files_in_group \* innodb_log_file_size = innodb_redo_log_capacity). If none of those variables are set, redo log capacity is set to the innodb_redo_log_capacity default value, which is 104857600 bytes (100MB). The maximum redo log capacity is 128GB.
132135
133-
> Redo log files reside in the #innodb_redo directory in the data directory unless a different directory was specified by the innodb_log_group_home_dir variable. If innodb_log_group_home_dir was defined, the redo log files reside in the #innodb_redo directory in that directory. There are two types of redo log files, ordinary and spare. Ordinary redo log files are those being used. Spare redo log files are those waiting to be used. InnoDB tries to maintain 32 redo log files in total, with each file equal in size to 1/32 * innodb_redo_log_capacity; however, file sizes may differ for a time after modifying the innodb_redo_log_capacity setting.
136+
> Redo log files reside in the #innodb_redo directory in the data directory unless a different directory was specified by the innodb_log_group_home_dir variable. If innodb_log_group_home_dir was defined, the redo log files reside in the #innodb_redo directory in that directory. There are two types of redo log files, ordinary and spare. Ordinary redo log files are those being used. Spare redo log files are those waiting to be used. InnoDB tries to maintain 32 redo log files in total, with each file equal in size to 1/32 \* innodb_redo_log_capacity; however, file sizes may differ for a time after modifying the innodb_redo_log_capacity setting.
134137
135-
意思是在 MySQL 8.0.30 之前可以通过 `innodb_log_files_in_group``innodb_log_file_size` 配置日志文件组的文件数和文件大小,但在 MySQL 8.0.30 及之后的版本中,这两个变量已被废弃,即使被指定也是用来计算 `innodb_redo_log_capacity` 的值。而日志文件组的文件数则固定为32,文件大小则为 `innodb_redo_log_capacity / 32`
138+
意思是在 MySQL 8.0.30 之前可以通过 `innodb_log_files_in_group``innodb_log_file_size` 配置日志文件组的文件数和文件大小,但在 MySQL 8.0.30 及之后的版本中,这两个变量已被废弃,即使被指定也是用来计算 `innodb_redo_log_capacity` 的值。而日志文件组的文件数则固定为 32,文件大小则为 `innodb_redo_log_capacity / 32`
136139

137140
关于这一点变化,我们可以验证一下。
138141

@@ -144,7 +147,7 @@ innodb_log_file_size = 10485760
144147
innodb_log_files_in_group = 64
145148
```
146149

147-
docker启动一个 MySQL 8.0.32 的容器:
150+
docker 启动一个 MySQL 8.0.32 的容器:
148151

149152
```bash
150153
docker run -d -p 3312:3309 -e MYSQL_ROOT_PASSWORD=your-password -v /path/to/your/conf:/etc/mysql/conf.d --name
@@ -163,7 +166,7 @@ MySQL830 mysql:8.0.32
163166

164167
![](images/redo-log.png)
165168

166-
可以看到刚好是32个,并且每个日志文件的大小是 `671088640 / 32 = 20971520`
169+
可以看到刚好是 32 个,并且每个日志文件的大小是 `671088640 / 32 = 20971520`
167170

168171
所以在使用 MySQL 8.0.30 及之后的版本时,推荐使用 `innodb_redo_log_capacity` 变量配置日志文件组
169172

@@ -329,16 +332,11 @@ MySQL InnoDB 引擎使用 **redo log(重做日志)** 保证事务的**持久性*
329332

330333
`MySQL`数据库的**数据备份、主备、主主、主从**都离不开`binlog`,需要依靠`binlog`来同步数据,保证数据一致性。
331334

332-
## 站在巨人的肩膀上
335+
## 参考
333336

334337
- 《MySQL 实战 45 讲》
335338
- 《从零开始带你成为 MySQL 实战优化高手》
336339
- 《MySQL 是怎样运行的:从根儿上理解 MySQL》
337340
- 《MySQL 技术 Innodb 存储引擎》
338341

339-
## MySQL 好文推荐
340-
341-
- [CURD 这么多年,你有了解过 MySQL 的架构设计吗?](https://mp.weixin.qq.com/s/R-1km7r0z3oWfwYQV8iiqA)
342-
- [浅谈 MySQL InnoDB 的内存组件](https://mp.weixin.qq.com/s/7Kab4IQsNcU_bZdbv_MuOg)
343-
344342
<!-- @include: @article-footer.snippet.md -->
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png)
1+
![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png)
2+

0 commit comments

Comments
 (0)