阅读innodb double write文档

This commit is contained in:
wuxiangkai
2024-12-19 12:58:47 +08:00
parent ba967259bd
commit 5bf56c33db

View File

@@ -441,3 +441,66 @@ change buffer可以带来更少的磁盘读取和磁盘写入故而在工作
当change buffer占用了过多buffer pool中内存导致buffer pool中页面老化速度超出预期时此时可以尝试将`innodb_change_buffer_max_size`适当调小。
## double write
double write buffer为存储区域当innodb将buffer pool中的页刷新到innodb data file中的适当位置之前会页写入到double write buffer中。
如果在写入页面的过程中发生操作系统、存储子系统、mysql进程的异常通过double write buffer在crash recovery的过程中innodb能够从double write buffer中找到page的备份。
即使数据写了两次double write buffer也不会造成两倍的IO负载或两倍的io操作数量。数据按照large chunk的方式写入到double write buffer中并且会调用`fsync`方法。
### double write结构
double write由两部分组成
- 内存: double write buffer位于内存中
- 磁盘:磁盘中的表空间
当innodb刷新buffer pool中的页面时操作如下
1. 将页面写入到double write buffer中其含有128个页并且在写入到double write buffer后调用`fsync`确保将double write buffer中的数据刷新到磁盘中
2. 在完成`1`操作后会实际将页数据写入到data file磁盘文件中再次调用`fsync`确保数据被持久化到磁盘中
在后续innodb执行recovery操作时会检查double write buffer中的内容和data file中page的内容
- 如果double write buffer中内容不一致那么仅会将double write buffer中的内容丢弃
- 如果datafile中页内容不一致那么将会从double write buffer中恢复数据
### innodb_doublewrite
`innodb_doublewrite`控制是否启用double write buffer。默认情况下double write开启。如果想要关闭double write可以将`innodb_doublewrite`设置为`OFF`.
#### DETECT_AND_RECOVERY
`DETECT_AND_RECOVERY``ON`设置相同在该设置下double write被完全启用。innodb将会将page内容写入到double write buffer中并且在recovery过程中会通过double write buffer中的数据来修复不一致page。
#### DETECT_ONLY
`innodb_doublewrite`被设置为`DETECT_ONLY`只有元数据会被写入到double write buffer数据库的page content并不会被写入到double write buffer中并且recovery过程也不会用double write buffer中的内容来恢复数据。
`DETECT_ONLY`设置只是为了检测`incomplete page write`
> 如果dobule write buffer位于支持`atomic write`的fusion-io设备上那么double write buffer将会自动被关闭datafile的写入将会使用`fusion-io atomic write`。
### innodb_doublewrite_dir
`innodb_doublewrite_dir`变量定义了innodb创建doublewrite files的位置。如果该变量没有被指定那么innodb将会把文件创建在`innodb_data_home_dir`
### innodb_doublewrite_pages
`innodb_doublewrite_pages`控制每个线程其doublewrite page的最大数量。
### innodb_doublewrite_files
`innodb_doublewrite_files`定义了doublewrite file的文件个数默认情况下值为2会为每个buffer pool instance创建两个doublewrite文件
- flush list doublewrite file
- lru list doublewrite file
#### flush list dobulewrite file
flush list doublewrite file是用于buffer pool flush list中page的刷新的。flush list doublewrite file的默认大小为`innodb page size * double write pages`
#### lru doublewrite file
lru doublewrite file是用于从buffer pool lru list中刷新的其默认大小为`innodb page size * (doublewrite pages + (512 / buffer pool instances))`
其中512为slot的总数量。
doublewirte file命名格式如下所示
```
#ib_page_size_file_number.dblwr
```