存储引擎
InnoDB:行锁、支持外键
非锁定读
支持事务
MyISAM:不支持事务、表锁和全文索引
MySQL连接方式
TCP/IP:权限视图
命名管道/共享内存
Unix域套接字
体系架构
- 内存池负责:
1.维护内部数据结构
2.缓存磁盘数据
3.redo log缓冲
- 后台线程负责:
1.刷新内存池中数据
2.将已修改的数据文件刷新到磁盘
后台线程
默认7个后台线程(4 IP, 1 master, 1 lock, 1 错误监控)
io线程:insert buffer thread
log thread
read thread(innoDB Plugin版本4个)
write thread(innoDB Plugin版本4个)
内存
组成部分:缓冲池,日志缓冲池,额外的内存池
工作方式:将数据库文件按页(16K)读取到缓冲池
按照LRU保留缓冲池中的缓冲数据
在缓冲池中的页上进行修改
按照一定频率将缓冲池的脏页刷新到文件
内存结构:
日志缓冲:将redo log先放入缓冲区,然后按一定频率刷新到redo log文件
- 额外内存池:
对内存的管理通过heap方式进行
对数据结构本身分配内存时,从额外的内存池申请(不够时从缓冲池申请)
数据结构本身包括:帧缓冲/缓冲控制对象,LRU、锁、等待信息
master thread
- main loop:
每秒执行的操作:
日志缓冲刷新到磁盘(总会,即使事务没提交也会)
合并insert buffer(当前IO压力小时执行)
刷新至多100个脏页到磁盘(脏页比例超过阈值时执行)
没有用户活动,则切换到background loop
每10秒执行的操作:
刷新100/10个脏页到磁盘(IO压力小时刷新100个脏页)
合并至多5个insert buffer(总会)
将日志缓冲刷新到磁盘(总会)
删除无用undo页(总会)
执行update, delete时,原先的行标记为删除
一致性读中需要保留这些行的版本信息
full purge过程中,判断当前事务系统中已被删除的行是否可以删除,如果可以则立即将其删除
产生一个检查点(总会)
模糊检查点,只将最老日志序列号的页写入磁盘
- background loop:
数据库空闲或关闭时的循环
执行操作:
删除无用undo页(总会)
合并20个insert buffer(总会)
跳回到主循环(不处于idle)
不断刷新100个页,直到符合条件(处于idle,跳转到flush loop中完成)
- suspend_loop
当flush loop没有事情可做
挂起master thread
缺陷:写密集时来不及处理;需要刷新的脏页阈值太大
补丁:提供参数记录磁盘I/O吞吐量,按照其百分比刷新页到磁盘
通过重做日志速度来判断最合适的刷新脏页的数量
关键特性
insert buffer
物理页的组成部分
- 条件:
1.非聚集索引;
2.不唯一的索引(不会判断数据唯一性,否则需要离散度,失去了insert buffer意义)
- 对于非聚集索引的插入或者更新:
离散地访问非聚集索引页性能太低
判断插入的非聚集索引页是否在缓冲池中:
在,直接插入
否则,放入insert buffer中,然后以一定频率执行insert buffer和非聚集索引叶子节点的合并操作
合并之后可能有多个索引在同一页,能够减少插入次数
doublewrite
解决partial page write
在写数据页之前,先把这个数据页写到一块独立的物理文件位置,然后再写到数据页。这样宕机重启时,如果出现数据页损坏,那么在应用redo log之前,需要通过该页的副本来还原该页,然后再进行redo log重做
1.当缓冲池的脏页刷新时,将脏页先拷贝到内存中的doublewrite buffer
2.通过doublewriter buffer分两次,每次写入1MB到共享表空间的物理磁盘
3.将doublewrite buffer中的页写入表空间文件中
自适应哈希索引
默认采用B+树索引
对经常访问的页构造哈希索引
通过缓冲池的B+树页构造
关闭的几种状态:
0:关闭时,需要完成所有full purge, merge insert buffer操作
1:将缓冲池的数据脏页刷新到磁盘
2:将日志写入日志文件,下次启动时会执行恢复操作