mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
[docs update] MySQL 日志内容完善
This commit is contained in:
parent
299f5656d1
commit
51aca7a0eb
@ -43,23 +43,26 @@ tag:
|
||||
|
||||
InnoDB 刷新重做日志的时机有几种情况:
|
||||
|
||||
1. 事务提交:当事务提交时,相关的重做日志会被刷新到磁盘。这确保了提交的事务对于恢复是可用的。
|
||||
InnoDB 将 redo log 刷到磁盘上有几种情况:
|
||||
|
||||
2. 事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘。
|
||||
|
||||
3. Checkpoints(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。
|
||||
|
||||
4. 后台刷新线程:InnoDB 启动了一个后台线程,负责周期性地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。
|
||||
1. 事务提交:当事务提交时,log buffer 里的 redo log 会被刷新到磁盘(可以通过`innodb_flush_log_at_trx_commit`参数控制,后文会提到)。
|
||||
2. log buffer 空间不足时:log buffer 中缓存的 redo log 已经占满了 log buffer 总容量的大约一半左右,就需要把这些日志刷新到磁盘上。
|
||||
3. 事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘。
|
||||
4. Checkpoint(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。
|
||||
5. 后台刷新线程:InnoDB 启动了一个后台线程,负责周期性(每隔 1 秒)地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。
|
||||
6. 正常关闭服务器:MySQL 关闭的时候,redo log 都会刷入到磁盘里去。
|
||||
|
||||
总之,InnoDB 在多种情况下会刷新重做日志,以保证数据的持久性和一致性
|
||||
|
||||
`InnoDB` 存储引擎为 `redo log` 的刷盘策略提供了 `innodb_flush_log_at_trx_commit` 参数,它支持三种策略:
|
||||
我们要注意设置正确的刷盘策略`innodb_flush_log_at_trx_commit` 。根据 MySQL 配置的刷盘策略的不同,MySQL 宕机之后可能会存在轻微的数据丢失问题。
|
||||
|
||||
- **0**:设置为 0 的时候,表示每次事务提交时不进行刷盘操作
|
||||
- **1**:设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值)
|
||||
- **2**:设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache
|
||||
`innodb_flush_log_at_trx_commit` 的值有 3 种,也就是共有 3 种刷盘策略:
|
||||
|
||||
`innodb_flush_log_at_trx_commit` 参数默认为 1 ,也就是说当事务提交时会调用 `fsync` 对 redo log 进行刷盘
|
||||
- **0**:设置为 0 的时候,表示每次事务提交时不进行刷盘操作。这种方式性能最高,但是也最不安全,因为如果 MySQL 挂了或宕机了,可能会丢失最近 1 秒内的事务。
|
||||
- **1**:设置为 1 的时候,表示每次事务提交时都将进行刷盘操作。这种方式性能最低,但是也最安全,因为只要事务提交成功,redo log 记录就一定在磁盘里,不会有任何数据丢失。
|
||||
- **2**:设置为 2 的时候,表示每次事务提交时都只把 log buffer 里的 redo log 内容写入 page cache(文件系统缓存)。page cache 是专门用来缓存文件的,这里被缓存的文件就是 redo log 文件。这种方式的性能和安全性都介于前两者中间。
|
||||
|
||||
刷盘策略`innodb_flush_log_at_trx_commit` 的默认值为 1,设置为 1 的时候才不会丢失任何数据。为了保证事务的持久性,我们必须将其设置为 1。
|
||||
|
||||
另外,`InnoDB` 存储引擎有一个后台线程,每隔`1` 秒,就会把 `redo log buffer` 中的内容写到文件系统缓存(`page cache`),然后调用 `fsync` 刷盘。
|
||||
|
||||
@ -128,11 +131,11 @@ InnoDB 刷新重做日志的时机有几种情况:
|
||||
|
||||
注意从 MySQL 8.0.30 开始,日志文件组有了些许变化:
|
||||
|
||||
> 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.
|
||||
> 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.
|
||||
|
||||
> 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.
|
||||
> 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.
|
||||
|
||||
意思是在 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` 。
|
||||
意思是在 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` 。
|
||||
|
||||
关于这一点变化,我们可以验证一下。
|
||||
|
||||
@ -144,7 +147,7 @@ innodb_log_file_size = 10485760
|
||||
innodb_log_files_in_group = 64
|
||||
```
|
||||
|
||||
docker启动一个 MySQL 8.0.32 的容器:
|
||||
docker 启动一个 MySQL 8.0.32 的容器:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||

|
||||
|
||||
可以看到刚好是32个,并且每个日志文件的大小是 `671088640 / 32 = 20971520`
|
||||
可以看到刚好是 32 个,并且每个日志文件的大小是 `671088640 / 32 = 20971520`
|
||||
|
||||
所以在使用 MySQL 8.0.30 及之后的版本时,推荐使用 `innodb_redo_log_capacity` 变量配置日志文件组
|
||||
|
||||
@ -329,16 +332,11 @@ MySQL InnoDB 引擎使用 **redo log(重做日志)** 保证事务的**持久性*
|
||||
|
||||
`MySQL`数据库的**数据备份、主备、主主、主从**都离不开`binlog`,需要依靠`binlog`来同步数据,保证数据一致性。
|
||||
|
||||
## 站在巨人的肩膀上
|
||||
## 参考
|
||||
|
||||
- 《MySQL 实战 45 讲》
|
||||
- 《从零开始带你成为 MySQL 实战优化高手》
|
||||
- 《MySQL 是怎样运行的:从根儿上理解 MySQL》
|
||||
- 《MySQL 技术 Innodb 存储引擎》
|
||||
|
||||
## MySQL 好文推荐
|
||||
|
||||
- [CURD 这么多年,你有了解过 MySQL 的架构设计吗?](https://mp.weixin.qq.com/s/R-1km7r0z3oWfwYQV8iiqA)
|
||||
- [浅谈 MySQL InnoDB 的内存组件](https://mp.weixin.qq.com/s/7Kab4IQsNcU_bZdbv_MuOg)
|
||||
|
||||
<!-- @include: @article-footer.snippet.md -->
|
@ -1 +1,2 @@
|
||||

|
||||

|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user