MySQL innoDB 存储引擎学习篇(二)

2015-02-25 15:03:57 · 作者: · 浏览: 71
ed_flush_rate的函数来判断需要刷新脏页最合适的数量。而buf_flush_get_desired_flush_rate是通过判断产生重做日志的速度来判断最合适的刷新脏页的数量。因此当脏页的比例小于Innodb_max_dirty_pages_pct时,也会刷新一定量的脏页。


?


? ? ? ? 关键性
? ? ? ? Innodb存储引擎的关键性特性包括插入缓冲、两次写(double wirte)、自适应哈希索引(adaptive hash index)。
? ? ? ? 插入缓冲
? ? ? ? 插入缓冲是Innodb存储引擎关键特性;Insert Buffer和数据页一样,也是物理页的一个组成部分;
? ? ? ? 聚集索引一般是顺序的,不需要磁盘的随机读取,
? ? ? ? 在很多情况下,一张表有多个非聚集的辅助索引(secondary index)
? ? ? ? InnoDB存储引擎开创性设计了插入缓冲,对于非聚集索引的插入或更新操作,不是每一次直接插入索引页中。而是先判断插入的非聚集索引页是否在缓冲池中。如果在,则直接插入;如果不在,则先放入一个插入缓冲区中,好似欺骗数据库这个非聚集索引已经查到叶子节点了.然后再以一定的频率执行插入缓冲和非聚集索引页子节点的合并操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对非聚集索引执行插入和修改操作的性能。
? ? ? ? 插入缓冲的使用需要满足以下两个条件:
? ? ? ? 1、索引是辅助索引。
? ? ? ? 2、索引不是唯一的。
? ? ? ? 辅助索引不能是唯一的,因为在把它插入到插入缓冲时,我们并不去查找索引页的情况。如果查找肯定会出现离散读的情况,插入缓冲就失去了意义.
? ? ? ? Ibuf: size 1, free list len 0, seg size 2, 38 merges
? ? ? ? seg size显示当前插入缓冲的大小为2*16KB
? ? ? ? free list len 0
? ? ? ? free list len 代表了空闲列表的长度。
? ? ? ? 目前插入缓冲存在一个问题是,在写密集的情况下,插入缓冲会占用过多的缓冲池内存,默认情况下最大可占用1/2的缓冲池内存。
? ? ? ? 修改IBUF_POOL_SIZE_PER_MAX_SIZE就可以对插入缓冲的大小进行控制;列如;将IBUF_POOL_SIZE_PER_MAX_SIZE改为3,则最大只能使用1/3的缓冲池内存.


? ? ? ? 两次写
? ? ? ? 如果说插入缓冲带给Innodb存储引擎的是性能,那么两次写带给Innodb存储引擎的数据的可靠性,当数据库戎机时,可能发生数据库正在写一个页面,而这个页只能写一部分(比如16K的页,只写前4K的页)的情况,我们称之为部分写失效(partial page write);
注意:重做日志中记录的是对物理操作,如偏移量800,写'aaa'记录。如果这个页本身已经损坏了,再对其进行重做是没有意义的。这就是说,在应用(apply)重做日志之前,我们需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是doublewrite.innodb存储引擎doublewerite;
? ? ? ? doublewrite由两部分组成:一部分是内存中的doublewrite buffer,大小为2MB;另一部分是物理磁盘上共享表空间中连续的128个页;即两个区(extent),大小同样为2MB;当缓冲池的脏页刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先拷贝到内存中的doublewrite buffer,之后通过doublewrite再分两次,每次写入1MB到共享表空间的物理磁盘上,然后马上调用fsync函数 ,同步磁盘,避免缓冲写带来的问题。在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的.开销并不是很大。在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,此时的写入则是离散的。可以通过以下命令观察double write运行状况;


?


mysql> show global status like 'innodb_dblwr%'\G;
*************************** 1. row ***************************
Variable_name: Innodb_dblwr_pages_written
? ? ? ? Value: 10005304
*************************** 2. row ***************************
Variable_name: Innodb_dblwr_writes
? ? ? ? Value: 3272391
2 rows in set (0.01 sec)


?