mysql技术内幕InnoDB存储引擎
基本信息
作者
姜承尧
类别
技术-mysql
简介
第二版
推荐指数
阅读日期
开始日期
终止日期
书摘
mysql体系结构和存储引擎
特点
可移植数据库
定义数据库和实例
定义
数据库
物理操作系统文件或者其他形式文件的集合
数据库是文件集合
数据库实例是程序
实例
后台线程+共享区域
数据库实例才是用于操作数据库文件
mysql
单进程多线程架构数据库
mysql数据库实例在系统的表现上是一个进程
mysql的体系结构
基本组成
连接池组件
管理服务与工具组件
sql接口组件
查询分析器组件
优化器组件
缓冲组件
插件式存储引擎
区别于其他数据库的重要特点
存储引擎是基于表,不是基于数据库
物理文件
mysql的存储引擎
每个存储引擎有各自的特点
INNODB存储引擎
面向在线事务处理引擎
支持事务
行锁设计
支持外键
默认读取不会产生锁
mysql 5.5.8版本开始,INNODB作为默认存储引擎,5.5之前默认myisam
mysql4.1开始,可以将每个Innodb的表单独存放在一个独立的ibd文件中
Innodb存储引擎支持用裸设备(row disk)建立表空间
MVCC(多版本控制,获得高并发)
实现隔离级别
默认隔离级别repataable
next-key-locking的策略避免幻读
特殊功能
插入缓冲
二次写
自适应hash索引
预读
默认按照主键的顺序进行存放,未指定主键,innodb存储引擎为每一行生成6字节主键
myisam存储引擎
不支持事务,表锁
支持全文索引
缓冲池只缓存索引文件
myisam独有
数据文件交给操作系统完成
NDB存储引擎
集群存储引擎
数据全部放到内存
mysql5.1 之后,可以将非索引放到磁盘上,因此主键查找特别快
NDB存储join表 是在mysql底层实现的,因此查询特别慢
memory 存储引擎
数据存储内存中
重启或者程序崩溃,数据丢失
默认hash索引
只支持表锁
并发性能差
不支持text&bolb类型
超过容量,转换成myisam引擎,进行磁盘存放
archive引擎
只支持insert&select操作
mysql 5.1开始支持索引
高效的插入和查询 适合归档数据
本身不是事务安全的存储引擎
Federated存储引擎
不存放数据,只是指向一张远程mysql数据库上的表 ,类似透明网关
只支持mysql数据表,不支持异构数据库表
maria存储引擎
支持缓存数据和索引
应用行锁设计
提供了MVCC功能
支持事务和非事务安全选项以及更好的BLOB字符类型的处理性能
其他存储引擎
根据存储引擎选择合适的使用场景
mysql部分存储引擎支持全文索引
随着数据增加,性能有所下降,但是不是线性下降
存储引擎的比较
链接mysql
本质是进程通信
进程通信方式
管道
命名管道
命名字
TCP/IP套接字
UNIX域套接字
InnoDB存储引擎
innodb引擎概述
特点
innodb是事务安全的存储引擎
第一个完整支持ACID事务的mysql存储引擎
行锁
支持MVCC
支持外键
提供一致性非锁定读
最有效利用内存和CPU
高性能 高可用 高扩展
innodb引擎版本比较
老版本:支持ACID.行锁设计,MVCC
1.0:继承老版本功能,新增compress和dynamic页格式
1.1:继承1.0版本,新增linuxAIO,多回滚段
1.2:继承1.1功能,增加全文索引支持,在线索引添加
innodb体系架构
后台线程
刷新内存吃中数据
修改的数据刷新到磁盘
多线程模型,不同线程处理不同任务
Master Thread
核心线程
异步刷新缓冲数据到磁盘
保证数据一致性
脏页数据刷新
合并插入刷新
UNDO页的回收
IO Thread
大量使用AIO处理IO请求
Purge Thread
事务提交后,回收undo页线程
Page Cleaner Thread
分担Master Thread工作,脏页数据刷新,该线程完成
内存
特点
维护所有进程/线程需要访问多个内部数据结构
缓存磁盘数据,方便快速读取
重做日志
缓冲池
缓存数据页类型
索引页
数据页
undo页
插入缓冲页
自适应hash索引
innodb存储锁信息
数据字典信息
索引页和数据页只占用了缓冲池的一部分
缓冲池数量可以配置,,多个缓冲池采用hash策略分配数据
LRUlist FreeList FlushList
LRU
管理已经读取的页码
优化的LRU算法,淘汰最不经常用的数据,但是新数据默认在列表的5/8(可配置)处
LRU列表被修改之后,称为脏页,需要checkoutpoint机制刷新脏页数据到磁盘
Free : LRU无数据时间,先从free读取,放到LRU之后,删除Free页数据
Flush页数据即为脏页数据
重做日志缓冲
额外的内存池
Checkpoint技术
缩短数据库恢复时间
缓冲池不够用的时候,将脏页数据刷新到磁盘
重做日志不可用的时候,刷新脏页
Master Thread 工作方式
主要工作都是单独后台线程Master Thread 中完成的
Innodb1.0.x版本之前的Master Thread
最高线程优先级别
loop
主循环
后台循环
刷新循环
暂停循环
Master Thread会根据数据库运行的状态中进行切换
每秒一次操作内容
日志缓冲刷新到磁盘(即使这个事务还没有提交)
合并 插入缓存
不是每秒都会发生,判断前一秒IO次数是否超过5次,小于5次可以执行合并插入
至多刷新100个InnoDB缓冲池中的脏页到磁盘
不是每秒都发生,判断脏页数据是否超过阈值
如果当前没有用户活动吗,切换到后台循环
每10秒的操作
刷新100个脏页到磁盘
合并至多5个插入缓冲
将日志缓冲插入到磁盘
删除无用的undo页
后台循环线程
没有用户活动(数据库空闲)||数据库关闭
删除无用Undo页码
合并20个插入缓冲
跳回住循环
不断刷新100个页直到符合循环
InnoDB关键特性
插入缓冲
插入页和数据页也是物理页的一部分
插入聚集索引一般是顺序的
使用条件
索引是辅助索引
索引不是唯一的
用于提升性能
两次写
用于提升可靠性
解决了脏页数据写入过程中突然丢失的问题
自适应hash索引
非常快的查找方法
自动监测表上各个索引页查询,如果建立hash索引可以带来速度提升,则建立hash索引
Innodb存储引擎会根据自动访问频率和模式自动的为索引页建立哈希索引
使用要求
以该模式访问了100次
页通过该模式访问了N次,其中 N = 页中记录* 1/16
异步IO
AIO的优势是可以进行IO Merage操作,也就是将多个IO合并为一个IO
刷新临近页
刷新附近脏页
启动关闭与恢复
文件
参数文件
特点
mysql数据库的参数文件,是以文本方式进行存储的
什么是参数
配置文件
参数类型
静态参数(不可修改)
动态参数(可以修改)
日志文件
error log
定位问题
binlog
记录了所有mysql数据更改的 操作 不包含 select 和show
作用
恢复
复制
审计
判断是否对数据库有攻击
默认情况,二进制文件并不是每次写的时候同步磁盘
slow quert log
定位慢sql
log
套接字文件
pid文件
进程ID写入文件,即为pid文件
表结构定义文件
InnoDB存储引擎文件
表空间文件
重做日志文件
表
索引组织表
索引组织表:在innodb存储引擎中,表都是根据主键顺序组织存放的
未显示创建主键
表中是否有非空唯一索引,有当作主键
没有唯一非空索引情况下,自动创建6字节大小指针
InnoDB逻辑存储结构
表空间
存储引擎逻辑结构最高层
段
数据段
索引段
回滚段
区
连续页形成的空间 大小为1M
页
innodb磁盘管理的最小单位
常见页了类型
数据页
undo页
系统页
事务数据页
插入缓冲页
插入缓冲空闲列表页
未压缩的二进制大对象页
压缩的二进制大对象页
行
innodb存储引擎是面向列的,数据按照行存储
InnoDB行记录格式
InnoDB数据页结构
Name FIle Formats机制
约束
关系型数据库可以保持存储数据的完整性
视图
视图:命名的虚表
没有实际的物理存储
物化视图
分区表
分区类型
range分区
list分区
hash分区
key分区
子分区
索引与算法
索引太多太少都会影响性能
存储引擎概述
常见索引
B+树索引
全文索引
hash索引
数据结构与算法
二分查找法
二分
二叉查找树和平衡二叉树
二叉查找树
左子树小于根
右子树大于根
中序遍历: 左中右
平衡二叉树
又叫AVL树
任意两个节点两个子树的高度差为1
B+树
B+树索引
索引的本质是树在数据库的实现
聚集索引
按照表的主键构造一颗B+树
每个数据页通过一个双向链表进行链接
聚集索引的数据页,逻辑上通过双向链表实现有序,物理存储上是无序的
主键的排序查找和范围查找特别快
mysql中的文件排序(filesort)
辅助索引(非聚集索引)
叶子节点不包含行记录的全部数据
B+树索引的分裂
B+树的索引管理
索引管理
B+树索引的使用
联合索引
联合索引也是一颗B+树
覆盖索引
不包含整行记录的所有数据,数据会相对小,减少IO次数
优化器选择不使用索引的情况
范围查找
join表链接操作
哈希表
散列表
自适应hash索引
全文检索
倒排索引实现全文检索
是一种索引结构
辅助表中存储单词或者文档位置的映射
Innodb全文检索
每张表只能有一个全文检索的索引
多列组合而成的全文索引必须使用相同的字符集和排序规则
不支持没有单词的界定符,中文,日语,韩语
倒排索引是什么?
最左匹配原则
从最左开始匹配索引,遇到范围查找停止匹配索引
锁
什么是锁
管理对共享资源的并发控制
行锁
表锁
lock与latch
latch
互斥锁
读写锁
没有死锁检测机制
轻量级锁
lock
锁的对象是事务
有死锁机制
innodb存储引擎中的锁
锁的类型
共享锁
允许事务读一行数据
互斥锁
允许事务删除或者更新一行数据
innodb支持多粒度锁定
意象锁
锁定的对象分为多个层次
意象共享锁:事务想要获得一张表中某几行的共享锁
意象排他锁:事务想要获得一张表中的某几行的排他锁
意象锁不会阻塞除全表扫描以外的任何请求
一致性非锁定读
读取delete||update的数据,不会等待修改的锁释放影响读的数据操作
不是每个事务隔离级别都是采用非锁定一致性读
提高了并发
通过undo页的快照实现
每行记录可能有多个版本
隔离级别不同版本数量不同
read committed
总是读取最新快照
repeateable read
非一致性读总是读取事务开始时候的版本数据
innodb对于select语句支持两种锁定读
select ......for update
其他sql不允许加任何锁
select ...... lock in share mode
其他sql可以添加S锁,如果加X锁 会被阻塞
自增长与锁
外键和锁
锁的算法
行锁的3种算法
recoed lock:单个行记录上的锁
gap lock:间隙锁
锁定一个范围,但是不包含记录本身
next -key lock
锁定一个范围,包含本身
查询列有唯一索引,降级为record lock(提高性能)
锁问题
脏读
读取到其他事务未提交的数据
脏读不同于脏页
脏页:缓存池中已经被修改的数据
未刷新到磁盘中
已经写到重做日志中
脏页是因为数据库实例内存和磁盘的异步造成的
脏数据:事务对缓冲池中的行记录修改,并且还没有提交
违反了数据库隔离性
不可重复读
一个事务内多次读取同一个数据集合
不可重复读,读取的是已经提交的数据(不同于脏读,脏读读取的是未提交的数据)
违反了事务一致性的要求
mysql的存储引擎默认隔离级别是 read repeateble
避免的问题是幻想问题(phantom problem)
丢失更新
串行化能解决这种问题
两个事务先后顺序的覆盖提交 导致数据不一致
阻塞
阻塞可以确保事务正常并发 运行
死锁
资源相互持有不释放
解决方案
任何等待都转化为回滚,事务重新开始,但是会有并发性能下降问题
死锁时间,设置一个事务超时,一个事务回滚,另外一个事务就可以继续进行
事务undo 页过大,事务回滚时间可能超过
wait for graph :
innodb采取的检测方式
深度优先算法实现
图保存的两种信息
锁的信息链表
事务的等待链表
主动检测方式
链表构造一张图,图中存在回路,则存在死锁
死锁的示例
程序是串行的,不可能发生死锁
锁升级
行锁-页锁-表锁
事物
事务是区别文件系统的重要特性之一
事务特性
ACID
认识事务
原子性
一致性
隔离性
持久性
事务分类
扁平事务
使用最多
带有保存点的扁平事务
发生异常,可以回到保存点
链事务
链表事务回滚,仅限于当前事务
嵌套事务
顶层事务
顶层事务全部提交,子事务才全部提交
子事务
ACI 没有D的特性
分布式事务
事务的实现
redo 日志
实现事务的持久性
性能瓶颈是调用fsync 同步日志到磁盘
在innodb存储引擎层产生
物理格式文件,记录每个页的修改
日志文件不断被写入,跟时间没关系
undo 日志
帮助实现MVCC 以及事务回滚
记录了事务的行为
当前记录被事务A占用,通过undo日志返回之前行版本的信息
二进制日志
任何存储引擎都会产生
数据库层产生
只有事务提交之后会产生二进制日志
group commit
事务提交的操作
修改内存中事务对应的信息,将日志写入重做日志缓冲
调用fsync 将确保日志都从重做日志缓冲写入磁盘
事务的控制语句
隐式提交sql语句
对于事务操作的统计
必须显示提交才会统计计算
事务的隔离级别
大多数数据库没有提供真正的隔离性
隔离级别越低,事务请求的锁越少,保持锁的时间越短
分布式事务
mysql数据库分布式事务
允许多个独立事务资源
要么都提交 要么都回滚
XA事务
资源管理器
提供访问事务的方法,通常一个数据库就是一个资源管理器
事务管理器
协调参与全局事务中的各个事务,,需要参与全局事务中的所有资源管理器进行通讯
应用程序
定义事务的边界,指定全局事务中的操作
分布式事务
两阶段提交
第一阶段准备提交
第二阶段,回滚或者提交
备份与恢复
备份与恢复概述
hot Backup
又叫做在线备份,不会影响数据库运行
Cold Backup
数据库停止运行备份,只需要拷贝文件
特点
备份简单,复制文件就可
跨系统恢复数据简单
恢复速度快,只需要文件放到指定位置,不需要执行sql,不需要重建索引
文件比较大
文件大小写敏感
Warm Backup
数据库运行期间备份,对数据操作有影响
加一个全局读锁保证数据一致性
备份文件 类型2
逻辑备份
裸文件备份
备份内容来分
完全备份
增量备份
日志备份
性能调优
选择合适的CPU
内存的重要性
硬盘对数据库性能的影响
合理的使用RAID
操作系统的选择也很重要
不同文件系统对数据库的影响
选择合适的基准测试工具
收获 & 感悟
书评