许久没有更新博客,上周末放假把网易大牛姜sir的著作MYSQL技术内幕InnoDB存储引擎又翻阅了一番,对当前工作的InnoDB特性有了一些新的认识,下面谈谈自己的读后感.
1. InnoDB的体系架构由一系列后台线程,内存池和文件组成,这点与其他DB有相似之处. 在内存中划分了一块区域,即缓冲池,用来临时存放用户读写的数据页. InnoDB上对缓冲池读写数据页,刷新到磁盘等操作也使用了CHECKPOINT机制,LRU算法,这点与SQLSERVER,DB2等数据库设计一致,这里不再阐述.需要注意的是MYSQL中指定LRU列表的midpoint控制位置由参数innodb_old_blocks_pct控制,该参数决定了新读取的页会插入到LRU尾部多少的位置.一般为37%.
2. 插入缓冲: 插入缓冲是InnoDB存储引擎开创性的设计,主要为了解决非聚集索引插入或更新操作时,由于非聚集索引离散地访问非聚集索引页,从而导致插入操作性能下降.这是因为非聚集索引本身的特性决定的.所以INNODB引入了插入缓冲这一特性,对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页,而是先判断插入的非聚集索引页是否在缓冲池中,若在则直接插入,如果不在则先放到到一个Insert Buffer对象中.然后再以一定的频率和情况进行Insert Buffer和辅助索引页子节点的合并操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这样大大提高了对于非聚集索引插入的性能.
插入缓冲的使用需要同时满足两个条件:1.索引为辅助索引;2.索引不是唯一的.因为在插入缓冲时,数据库并不去查找索引页来判断插入的记录的唯一性.如果去查找肯定又会有离散读取的情况发生,从而导致insert buffer失去了意义.
插入缓冲目前存在的问题主要是在写密集的情况下,插入缓冲会占用过多的缓冲池内存.
目前DB2,SQLSERVER上均没有插入缓冲这项特性.
3.Double-Write: 两次写主要带给InnoDB数据引擎的是数据页的可靠性.在其他数据库下,当某个数据页在正在写的过程中发生灾难,如电源问题导致宕机,该数据页会出现写失效的情况.当然我们可以通过重做日志进行恢复,但是由于重做日志记录的本身是对页的物理操作,如偏移量,写入记录等等.当物理页本身在宕机过程中损坏,再通过重做日志恢复不可行.面对这种情况,DB2,SQLSERVER通过内部命令REPAIRDB或者其他REPAIR工具去修复数据页.而MYSQL InnoDB两次写特性保证数据再在写入磁盘前先顺序写入共享表空间上,然后通过函数同步磁盘.这样相当于创建了数据页的一个副本.
4.自适应哈希索引:这是MYSQL INNODB另一个重要特性. InnoDB存储引擎会监控对表上各索引页的查询,如果观察到建立哈希索引可以带来速度提升,则自行建立哈希索引.InnoDB存储引起会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引.这个是SQLSERVER和DB2所不具备的