本文笔记摘自于《Mysql 技术内幕 InnoDB存储引擎》
Mysql InnoDB笔记(1)——体系架构
Mysql InnoDB笔记(2)——表
Mysql InnoDB笔记(3)——索引
Mysql InnoDB笔记(4)——锁
Mysql InnoDB笔记(5)——事务
Mysql InnoDB笔记(6)——备份和性能调优
Mysql包括多种存储引擎,主要有InnoDB和MyISAM,分别适用于不同的系统。
一般来说,InnoDB适用于OLTP的应用系统,从5.5.8版本开始,mysql默认的存储引擎是InnoDB。MyISAM适用于OLAP系统,不支持事务。
InnoDB由Innobase Oy公司开发,其特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,可以有效地利用内存和CPU。
InnoDB体系架构大致如下:
后台线程
Master Thread
后续详细介绍IO Thread
主要负责AIO的IO请求的回调处理Purge Thread
回收已经使用并分配的undo页。1.2版本开始支持配置多个Purge ThreadPage Cleaner Thread
刷新脏页
内存
缓冲池
允许配置多个缓冲池实例,主要缓存的数据有:数据页,索引页,undo页,插入缓冲,自适应哈希索引,锁信息,数据字典信息。
管理缓冲池的一些算法:LRU List FreeList Flush List重做日志缓冲
redo log在刷新到重做日志文件前,会缓存在缓存池里,然后通过一些机制刷新到日志文件额外的内存池
相当于备份的内存,其他区域的内存不足时,会在此申请
缓存数据刷新到磁盘的机制:Checkpoint,主要解决的问题:
缩短数据库恢复的时间;
缓冲池不够用时,将脏页刷新到磁盘;
重做日志不可用时,刷新脏页。
Master Thread
具有最高的线程优先级,由多个循环组成:
主循环 loop
每1秒的操作:
日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
合并插入缓冲(可能)
至多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能)
如果当前没有用户操作,则切换到backgroup loop(可能)每10秒的操作:
刷新100个脏页到磁盘(可能)
合并至多5个插入缓冲(总是)
将日志缓冲刷新到磁盘(总是)
删除无用的undo页(总是)
刷新100个或者10个脏页到磁盘(总是)
这些固定的数字在1.2.x版本开始都是可配置的
后台循环 backgroup loop
在数据库空闲或者关闭数据库时会切换到此循环,执行以下操作:
删除无用的undo页(总是)
合并20个插入缓冲(总是)
跳回到主循环(总是)
不断刷新100个页直到符合条件(可能,跳转到flush loop中完成)刷新循环 flush loop
暂停循环 suspend loop
InnoDB关键特性
这些特性保证了InnoDB的高性能及可靠性。
插入缓冲 Insert Buffer(高性能)
Insert Buffer不是缓冲,它只是存在缓冲池里的物理页的一个组成部分。本质是存放在共享空间中的一棵B+树。
Insert Buffer/Change Buffer使用条件:非唯一的辅助索引。为何呢?第一,因为聚集索引的操作一般都是顺序的,不存在随机读取的情况,操作非常速度,也就没必要buffer了。第二,如果辅助索引是唯一的,在操作的时候需要去查询索引页判断唯一性,这是离散读取的,就会失去buffer设计的目的了。Merge Insert Buffer触发的情况:
辅助索引页被读取到缓冲池时
Insert Buffer Bitmap页追踪到该辅助索引页已无可用空间时
Master Thread
插入或更新辅助索引时,先在Insert Buffer中操作,然后等待时机,将多个操作合并成一个操作,一起更新到真正的索引页中。
- 两次写 Double Write(可靠性)
dw由2部分组成,一部分是内存中的dw buffer,一部分是物理磁盘上共享表空间连续的128个页。
脏页刷新时,并不是直接写磁盘。而是先复制到内存中的dw buffer,然后写到共享表空间,并马上同步到磁盘,因为是连接的页,因此速度非常快。然后再从dw buffer写到表空间文件,这个过程是离散的,比较耗时。一旦发生异常,则从共享表空间找到副本,复制到表空间文件,再应用重写日志,恢复数据。
某些特定的情况下,可以修改配置参数
skip_innodb_doublewrite关闭dw功能。
应用架构的稳定性设计可以参考此方案。
自适应哈希索引 AHI(高性能)
InnoDB监控对表上各索引页的查询,根据特定的条件,自动建立哈希索引。
条件:对此页的连续访问模式一样,访问次数达到100次,或者达到N次,N=页中记录/16。异步IO AIO(高性能)
除了异步外,还可以进行IO Merger操作。刷新邻接页 Flush Neighbor Page(高性能)
刷新脏页的时候,顺便检查邻接的页是否脏页,顺便一起刷新。
可以修改配置参数
innodb_flush_neighbors关闭此功能
文件
参数文件
Mysql启动时,需要读取的配置文件日志文件
包含以下几种日志文件:
错误日志:启动 运行 关闭的过程记录
慢查询日志:记录运行时间超过某个阈值的所有sql语句
查询日志:所有请求Mysql的信息
二进制日志(binlog):记录对Mysql的更改操作
binlog主要用于备份和同步,比如我们的一主多从的架构就是把binlog从master同步到slave,然后执行binlog的内容。
long_query_time设置慢查询超时阈值
log_slow_queries=ON打开慢查询功能
log_ouput=FILE/TABLE配置慢查询输出到文件或表里
- socket文件
- pid文件
记录进程id - Mysql表结构文件
frm文件 - 存储引擎文件
包含表空间文件(ibdata1、.ibd)和重做日志文件(redo log)