本章要点
1.Buffer Pool
2.数据页
3.Change Buffer
4.Log Buffer
1 BufferPool理解
数据库的所有数据最终都会落到磁盘,如果更新或查询数据的话,都走磁盘文件的随机读写的话,效率比较差,因此便引入了BufferPool。
Buffer Pool是数据库的内存缓冲区,MySQL为了提高效率,增删改操作首先就是针对这个内存中的Buffer Pool里的数据执行的,同时配合了后续的redo log、刷磁盘等机制和操作。
整个过程如下图:
对内存里的数据进行增删改的时候,MySQL同时会把增删改对应的日志写入redo log中,所以万一数据库突然崩溃也没关系,只要从redo log日志文件里读取出来你之前做过哪些增删改操作,瞬间就可以重新把这些增删改操作在你的内存里执行一遍,这就可以恢复出来你之前做过哪些增删改操作了。 当然对于数据更新的过程,他是有一套严密的步骤的,还涉及到undo log、binlog、提交事务、buffer pool脏数据刷回磁盘,等等。
2 数据页
数据页:是Innodb 存储引擎用于管理数据的最小磁盘单位。常见的页类型有数据页、Undo 页、系统页、事务数据页等。
我们现在说的就是数据页,它默认的页大小为 16KB,每个页中至少存储有 2 条或以上的行记录。
Buffer Pool中存放的是一个一个的数据页,而不是一行行的数据记录。
生产上一般是给buffer pool设置为机器内存的50%~60%左右, 比如你有32GB的机器,那么给buffer设置个20GB的内存,剩下的留给OS和其他人来用。
3 Change Buffer
Change Buffer是一种特殊的数据结构,主要是用来缓存对不在Buffer Pool中的数据,二级索引页面的更改,缓存的changes可能由 Insert 、Delete 和 Update的结果导致,然后在页面被其他读取操作加载到Buffer Pool的时候合并,从而避免了昂贵的磁盘I / O操作。
对于唯一索引来说,所有的更新都需要判断是否违反唯一性约束,因此唯一索引是不能使用change buffer 的,针对普通索引的更新操作,并且涉及到的数据页不在内存中,此时就会用到change buffer。
4 Log Buffer
Log Buffer(日志缓冲区)是一块内存区域用来保存要写入磁盘上的日子文件的数据。 Log Buffer的大小由innodb_log_buffer_size变量定义。默认大小为16MB。Log Buffer的内容会定期刷到磁盘上。大的Log Buffer让较大事务能够运行,而无需在事务提交之前将redo log中的数据写入磁盘。
因此,如果有DML操作并且会影响很多行这样是事务,增加日志缓冲区的大小可以节省磁盘IO。
它会存储InnoDB存储引擎层日志:redo日志和undo日志.
他是如何刷新到磁盘里的呢?
这里就用到了:innodb_flush_log_at_trx_commit这个参数,这个参数一共有三个数值分别是0,1,2:
- 0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。
- 1:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,该模式为系统默认。
- 2:每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。