Checkpoint
功能
刷新脏页到磁盘的操作,实现ACID中的Durability<br>,具体解决的问题的思路:每次刷新多少页到磁盘,每次从哪里取脏页,什么时候触发checkpoint
checkpoint的必要性
buffer pool 空间有限
redo log buffer 空间有限
什么是LSN(Log Sequence Number)
一个8字节的一直递增的整形数字,表示事务写入redo log 的字节总量,<br>每个页都有一个LSN 字段,redo log 中有LSN,checkpoint也有LSN
checklpoint类型
Sharp Checkpoint
数据库关闭时刷新所有脏页
Fuzy Checkpoint
数据库运行时刷新部分脏页
Fuzzy Check Point 的触发时机
Master Thread Checkpoint
FLUSH_LRU_LIST Checkpoint
LRU List中至少有n个页可用(innodb_Iru_scan_depth=100),该检查放在Page Cleaner Thread 中进行<br>
Async/Sync Flush Checkpoint
重做日志文件不可用用时强制将一些页刷新会磁盘,保证redo log buffer 循环使用
checkpoint_age = redo_lsn - checkpoint_lsn<br>async_water_mark = 75% * total_redo_log_file_size<br>sync_water_mark = 90% * total_redo_log_file_size<br>checkpoint_age<async_water_mark => 不执行checkpoint<br><br>async_water_mark<checkpoint_age<sync_water_mark => async checkpoint<br><br>checkpoint_age>sync_water_mark => sync checkpoint <br>
Dirty Page too Much Checkpoint
缓冲池脏页占比超过innodb_max_dirty_pages_pct,强制checkpoint 到磁盘,保证缓冲池有足够可用的页
Double Write
partitial write的问题定义
innodb的page size是16KB,操作系统的block size一般为4kb,磁盘io可能更小,所以innodb的一次脏页刷新到磁盘不能保证原子性,需要有一个机制来保证这个操作中断时磁盘上不会出现partitial write的问题
innodb 使用double write 来解决partitial write的问题,在对缓冲池的脏页进行flush时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次IMB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大。
可以通过skip_innodb_doublewrite禁用double write 功能
衍生问题:为什么Kafka InfluxDB Redis aof 不需要解决partitial write 的问题?<br>答案:Mysql 是in-place update 上面的这几个都是append only,不会更新原值<br>
自适应哈希索引(AHI)
对于固定模式的等值类查询的优化,辅助索引的查询效率B+树高度的影响,一般高度为3-4的样子,所以一次完成辅助索引搜索需要3-4次查询,AHI就是将多次查询用hashmap的方式优化到一次,但是只对等值类查询生效,DBA不需要关注AHI的,他属于引擎的自优化项
要求
该模式访问了1000次
页通过该模式访问了N(页中记录/16)次
异步IO
同时提交多次IO后等待IO结果,async可以做io request merge ,相比同步IO(提交单个IO等待结果)性能提升明显
innodb 1.1.x之前aio 通过innodb存储引擎代码模拟实现,之后的版本是内核级别的async io实现称为Native AIO
刷新邻接页(Flush Neighbor Page)
刷新脏页的时候检查该页所在的区是否存在脏页,如果存在那么一起刷新
面临的问题
脏页可能不怎么脏,刷新完了立即有变脏了怎么办
固态硬盘相较于机械硬盘IOPS较高,是否需要这个特性
针对上面两个问题,innodb提供配置可开启关闭刷新邻接页,但是机械硬盘强烈建议开启