阅读change buffer相关文档
This commit is contained in:
@@ -12,6 +12,51 @@ innodb内存池由多个内存块构成,内存快负责如下功能:
|
|||||||
|
|
||||||
在innodb存储引擎中,后台线程主要负责刷新内存池中的数据,保证内存缓存为最新状态。此时后台线程还负责将内存池中的修改刷新到磁盘中。
|
在innodb存储引擎中,后台线程主要负责刷新内存池中的数据,保证内存缓存为最新状态。此时后台线程还负责将内存池中的修改刷新到磁盘中。
|
||||||
|
|
||||||
|
## mysql存储结构
|
||||||
|
mysql存储结构如图所示
|
||||||
|

|
||||||
|
|
||||||
|
mysql存储结构主要分为两部分:
|
||||||
|
- 内存结构
|
||||||
|
- 磁盘存储结构
|
||||||
|
|
||||||
|
### 内存结构
|
||||||
|
mysql内存结构主要是为了管理和优化数据存储和数据检索,mysql内存结构包含:
|
||||||
|
- 缓冲区(Buffer Pool)
|
||||||
|
- Change Buffer
|
||||||
|
- 自适应哈希索引(Adaptive hash index)
|
||||||
|
- Log Buffer
|
||||||
|
|
||||||
|
#### Buffer Pool
|
||||||
|
buffer pool主要用于缓存经常访问的数据
|
||||||
|
|
||||||
|
#### change Buffer
|
||||||
|
change buffer主要用于缓存针对辅助索引页面的修改。当被修改的辅助索引页面不存在于内存中时,将修改缓存在change buffer中,当后续辅助索引页面被加载到内存中时,会将对该页面的修改进行合并。
|
||||||
|
|
||||||
|
#### Adaptive hash index
|
||||||
|
自适应哈希索引是一个内存结构,用于优化部分读取操作的性能。其提供了一个快速内存检索机制,用于加速对索引页的频繁访问。
|
||||||
|
|
||||||
|
#### log Buffer
|
||||||
|
log buffer是一个内存区域,用于存储将要被写入到transactiion log中的数据。
|
||||||
|
|
||||||
|
### 磁盘存储结构
|
||||||
|
innodb存储引擎将数据持久化存储到磁盘中。磁盘存储的结构如下所示:
|
||||||
|
- system tablespace
|
||||||
|
- file-per-table tablespaces
|
||||||
|
- general tablespaces
|
||||||
|
- undo tablespaces
|
||||||
|
- temporary tablespaces
|
||||||
|
- double write buffer
|
||||||
|
- redo log
|
||||||
|
- undo log
|
||||||
|
|
||||||
|
#### system tablespace
|
||||||
|
system tablespace作为change buffer的存储区域。
|
||||||
|
|
||||||
|
innodb用一个或多个文件来存储system tablespace,默认情况下,mysql会创建名为`ibdata1`的文件。
|
||||||
|
|
||||||
|
`innodb_data_file_path`决定了system tablespace files的大小和数量。
|
||||||
|
|
||||||
## 后台线程
|
## 后台线程
|
||||||
innodb采用多线程模型,存在多个后台线程,每种后台线程负责不同的后台任务。
|
innodb采用多线程模型,存在多个后台线程,每种后台线程负责不同的后台任务。
|
||||||
|
|
||||||
@@ -327,3 +372,72 @@ master thread中每秒一次的操作包括如下内容:
|
|||||||
- 将日志缓冲刷新到磁盘(总是)
|
- 将日志缓冲刷新到磁盘(总是)
|
||||||
- 删除无用的undo log页(总是)
|
- 删除无用的undo log页(总是)
|
||||||
|
|
||||||
|
## change buffer
|
||||||
|
change buffer为一个特殊的数据结构,当想要修改的辅助索引page不在缓冲区中时,会将针对辅助索引page的修改缓冲到change buffer中。
|
||||||
|
|
||||||
|
对于辅助索引页面的修改可能是由`insert, update, delete`操作造成的,当后续待修改的页面被读入到缓冲区中时,会对change buffer中缓冲的修改操作进行合并。
|
||||||
|
|
||||||
|
### 聚簇索引和辅助索引插入顺序
|
||||||
|
和聚簇索引不同,辅助索引通常不是唯一的。`并且,当使用`auto_increment`的聚簇索引时,新数据的插入通常都是顺序的(插入的多个数据唯一同一page中)。`
|
||||||
|
|
||||||
|
但是,当插入新数据时,新数据对应辅助索引记录的插入则相对是无序的,多条辅助索引记录的插入可能都分布在不同的page。同样的,针对辅助索引记录的修改和删除,其影响的辅助索引记录页可能分布在不同的索引页中。
|
||||||
|
|
||||||
|
通过change buffer,将针对辅助索引页面的修改缓冲在buffer中,并且当需要修改的辅助索引页面读取到缓冲区中时,再对change buffer中的修改操作进行合并,这样能很大程度上避免多次随机读取辅助索引页到缓冲区中带来的开销。
|
||||||
|
|
||||||
|
> 定期执行的purge操作会将被更新的索引页写入到磁盘中。相比于马上将被修改的索引页写入到磁盘中,purge操作更高效。
|
||||||
|
|
||||||
|
当存在很多被修改的行数据以及辅助索引数据时,change buffer merging操作可能花费数个小时来执行。在change buffer merging期间,磁盘IO将会增加,可能会导致磁盘相关查询的性能下降。
|
||||||
|
|
||||||
|
在内存中,change bufer占用的缓冲区的一部分,而在磁盘中,change buffer是system tablespace的一部分。当数据库实例未启动时,针对辅助索引的修改存储在磁盘的change buffer文件中。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
> 当辅助索引中包含`descending index column`或主键中包含`descending index column`时,change buffer不适用。
|
||||||
|
|
||||||
|
降序索引示例如下:
|
||||||
|
```sql
|
||||||
|
CREATE TABLE t (
|
||||||
|
c1 INT, c2 INT,
|
||||||
|
INDEX idx1 (c1, c2 DESC),
|
||||||
|
INDEX idx2 (c1 DESC, c2),
|
||||||
|
INDEX idx3 (c1 DESC, c2 DESC)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### change buffer配置
|
||||||
|
当对于table执行insert、update、delete一些列操作时,这些操作集合中辅助索引列的值通常是无序的(分散在多个辅助索引页中),如果大量更新多个索引页。`当待更新的辅助索引页不位于buffer pool中时,针对辅助索引页的修改将会被缓存。当待更新的索引页面被加载到buffer pool中时,被缓存的修改操作将会被合并,被更新的页面后续会刷新到磁盘中`。
|
||||||
|
|
||||||
|
> innodb在数据库实例空闲或slow shutdown时会进行change buffer的合并。
|
||||||
|
|
||||||
|
#### 优势
|
||||||
|
change buffer可以带来更少的磁盘读取和磁盘写入,故而在工作负载收到io限制时,change buffer能发挥重大作用。例如,在存在大量插入操作时,change buffer能够显著提升性能。
|
||||||
|
|
||||||
|
#### 弊端
|
||||||
|
由于change buffer会占用buffer pool的内存空间,故而当change buffer较大时,会减少数据缓存的可用空间。`但是,如果work set的大小和buffer pool几乎相当时,或是数据库表中几乎没有辅助索引时,此时则可以禁用change buffer`。
|
||||||
|
|
||||||
|
### `innodb_change_buffering`
|
||||||
|
`innodb_change_buffering`变量控制chnage buffer的行为,通过`innodb_change_buffering`,可以对如下操作进行启用和禁用:
|
||||||
|
- insert operations
|
||||||
|
- delete operations:`当index record被标记为删除`
|
||||||
|
- purge operations: `当index被物理删除`
|
||||||
|
|
||||||
|
> update操作是insert操作和delete操作的组合
|
||||||
|
|
||||||
|
`innodb_change_buffering`取值如下:
|
||||||
|
|
||||||
|
| value | numeric value | description |
|
||||||
|
| :-: | :-: | :-: |
|
||||||
|
| none | 0 | `默认`,不针对任何操作进行缓存 |
|
||||||
|
| inserts | 1 | 针对insert操作进行缓存 |
|
||||||
|
| deletes | 2 | 针对delete marking操作进行缓存 |
|
||||||
|
| changes | 3 | 针对inserts和delete-marking操作进行缓存 |
|
||||||
|
| purges | 4 | 针对后台发生的物理删除操作进行缓存 |
|
||||||
|
| all | 5 | 针对inserts, deletes, purges操作进行缓存 |
|
||||||
|
|
||||||
|
### `innodb_change_buffer_max_size`
|
||||||
|
`innodb_change_buffer_max_size`允许按照百分比的方式来配置change buffer占用buffer pool的最大大小,默认为`25`,最大可为`50`。
|
||||||
|
|
||||||
|
当mysql server存在大量insert、update、delete操作时,change buffer merging操作的速率无法跟上change buffer entries的新增速率,此时可以考虑增加`innodb_change_buffer_max_size`。
|
||||||
|
|
||||||
|
当change buffer占用了过多buffer pool中内存,导致buffer pool中页面老化速度超出预期时,此时可以尝试将`innodb_change_buffer_max_size`适当调小。
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user