你真的了解Innodb存储引擎?
前言
前几篇记录了如何查看SQL执行计划、数据库事务相关的知识点
除了这两个,数据库还有两个是非常重要的,必须要考的
就是存储引擎和索引
今天先记录以下InnoDB存储引擎相关的知识点
MySQL存储引擎
在MySQL存储引擎中,最为广知的存储引擎是InnoDB和MyISAM存储引擎
而这两个存储引擎的区别应该大家都清楚:
而MySQL目前默认的存储引擎就是InnoDB
「如何查看表使用的是哪种存储引擎?」
show table status like 'table_name'\G
InnoDB
是MySQL的默认事务性存储引擎,最重要、使用最广泛。
用来处理大量的短期事务。
InnoDB的性能和自动崩溃恢复特性,使得它在非事务性存储的需求中也有广泛的应用。
采用MVVC来支持高并发,并实现了四个标准的隔离级别,默认隔离级别是RR(Repeatable Read可重复读),并通过间隙锁来防止幻读的出现。
InnoDB表是基于聚簇索引建立的,聚簇索引对主键查询由很高的性能,不过它的二级索引(非主键索引)必须包含主键列。
「具体架构图如下」
上半部分是实例层(计算层),位于内存中
下半部分是物理层,位于文件系统中
实例层
分为线程和内存,Innodb重要的线程有Master Thread,此线程是Innodb的主线程,负责调度其他各线程。
Master Thread 的优先级最高, 其内部包含几个循环:
主循环(loop)
后台循环(background loop)
刷新循环(flush loop)
暂停循环(suspend loop)。
Master Thread 会根据其内部运行的相关状态在各循环间进行切换
大部分操作在主循环(loop)中完成,其包括1s和10s两种操作:
「1s操作:」
日志缓冲刷新到磁盘
最多刷新100个新脏页到磁盘
执行并改变缓冲的操作
若当前没有用户活动,可能切换到后台循环等
「10s操作:」
最多刷新100个新脏页到磁盘
合并至多5个被改变的缓冲
日志缓冲刷新到磁盘
删除无用的Undo页
刷新 100 个或者 10 个脏页到磁盘(总是)产生一个检查点(总是)等。
「buf dump thread:」
将缓存池中内容dump到磁盘中,实现MySQL热启动
「page_cleaner_thread:」
将缓存池的脏页刷新到磁盘
「purge thread:」
将不再使用的Undo页回收
「read_thread:」
处理读请求,并负责将数据页从磁盘中读取出来
「write_thread:」
负责将数据页从缓冲区写入磁盘,page_cleaner 线程发起刷脏页操作后就开始工作了。
「redo_log_thread:」
负责将日志缓冲区中的内容刷新到Redo log文件中
「insert_buffer_thread:」
负责把 Insert Buffer 中的内容刷新到磁盘
缓存结构
缓冲池中缓存的数据页类型有:
- 索引页
- 数据页
- undo页
- 插入缓冲(insert buffer)
- 自适应哈希索引(adaptive hash index)
- InnoDB存储的锁信息(lock info)
- 数据字典信息(data dictionary)
Redo log 日志缓存
InnoDB存储引擎会首先将重做日志信息先放入重做日志缓冲中,然后再按照一定频率将其刷新到重做日志文件
「缓冲页管理算法:」
页:磁盘管理的最小单位,默认16K。类型有:数据页,undo页,系统页
一般缓冲的管理算法就是LRU(Least recently used)。
一般是把刚如缓冲页的放在LRU的头部,作为最近访问的元素,最后的一个元素被淘汰。
(1)页已经在缓冲池里,那就只做“移至”LRU头部的动作,而没有页被淘汰;
(2)页不在缓冲池里,除了做“放入”LRU头部的动作,还要做“淘汰”LRU尾部页的动作;
比如:有一个LRU链
「第一种情况:」
查找元素为0的,那么链表就变成下面这样子
「第二种情况:」
查找元素为10的,但10不在链中,所以将10添加到head,而tail节点6去除
MySQL在此基础上进行了改造,原因是:
(1)预读失效:
「预读:」
磁盘读写,并不是按需读取,而是按页读取,一次至少读一页数据(一般是16K),如果未来要读取的数据就在页中,就能够省去后续的磁盘IO,提高效率。
「预读失效:」
预读(Read-Ahead)提前把页放入了缓冲池,但最终MySQL并没有从页中读取数据,称为预读失效。
「如何优化?」
(1)让预读失效的页,停留在缓冲池LRU里的时间尽可能短;
(2)让真正被读取的页,才挪到缓冲池LRU的头部;
所以MySQL将LRU分成两部分,分别是:
- 新生代
- 老生代
新老生代首位相连。
新页加入缓冲池时,只加入老生代的头部,
「如果数据真正被读取(预读成功),才会加入到新生代的头部」
「如果数据没有被读取,则会比新生代里的“热数据页”更早被淘汰出缓冲池」
新生代跟老生代的比例是 5 : 3
例如:绿色的是新生代,黄色是老生代
如果插入一个9的页,就是如下图:
老年代最后一个被淘汰
如果此时9被读取,那么就变成如下:
9称为新生代head节点,而原先新生代的tail节点5就变成老年代的head节点
(2)缓冲池污染
当一个SQL查询要扫描大量数据,导致把缓冲池中所有页全部替换,导致大量热数据被换出去,这就是缓冲池污染
MySQL在老生代中添加了停留时间窗口
如果数据被读取了并且在老身代中停留时间超过这个窗口,那么才会被加入新生代头部
「如何查看这个停留时间:」
参数innodb_old_blocks_time
「缓冲池相关参数:」
物理层
物理层在逻辑上分为
- 系统表空间
- 用户表空间
- Redo日志。
系统表空间里有 ibdata 文件和一些 Undo,ibdata 文件里有 insert buffer 段、double write段、回滚段、索引段、数据字典段和 Undo 信息段。
用户表空间是指以 .ibd 为后缀的文件,文件中包含 insert buffer 的 bitmap 页、叶子页(这里存储真正的用户数据)、非叶子页。InnoDB 表是索引组织表,采用 B+ 树组织存储,数据都存储在叶子节点中,分支节点(即非叶子页)存储索引分支查找的数据值。
Redo 日志中包括多个 Redo 文件,这些文件循环使用,当达到一定存储阈值(0.75)时会触发checkpoint 刷脏页操作,同时也会在 MySQL 实例异常宕机后重启,InnoDB 表数据自动还原恢复过程中使用。
用户读取或者写入的最新数据都存储在 Buffer Pool 中
如果 Buffer Pool 中没有找到则会读取物理文件进行查找,之后存储到 Buffer Pool 中并返回给 MySQL Server。Buffer Pool 采用LRU 机制。
Buffer Pool 决定了一个 SQL 执行的速度快慢,如果查询结果页都在内存中则返回结果速度很快,否则会产生物理读(磁盘读),返回结果时间变长,性能远不如存储在内存中。
「Redo 和 Undo」
Redo log 是一个循环复用的文件集,负责记录 InnoDB 中所有对 Buffer Pool的物理修改日志,当 Redo log文件空间中,检查点位置的 LSN 和最新写入的 LSN 差值(checkpoint_age)达到 Redo log 文件总空间的 75% 后,InnoDB 会进行异步刷新操作,直到降至 75% 以下,并释放 Redo log 的空间;当 checkpoint_age 达到文件总量大小的 90% 后,会触发同步刷新,此时 InnoDB 处于挂起状态无法操作。
Redo记录变更后的数据。
Undo记录事务数据变更前的值,用于回滚和其他事务多版本读。
「ARIES 三原则」
ARIES 三原则,是指 Write Ahead Logging(WAL)。
先写日志后写磁盘,日志成功写入后事务就不会丢失,后续由 checkpoint 机制来保证磁盘物理文件与 Redo 日志达到一致性;
利用 Redo 记录变更后的数据,即 Redo 记录事务数据变更后的值;
利用 Undo 记录变更前的数据,即 Undo 记录事务数据变更前的值,用于回滚和其他事务多版本读。
===============================
我是Liusy,一个喜欢健身的程序员。
获取更多干货以及最新消息,请关注_公_众_号:上古伪神
如果对您有帮助,点个关注、转发就是对我最大的支持!!!谢谢
你真的了解Innodb存储引擎?的更多相关文章
- [MySQL Reference Manual]14 InnoDB存储引擎
14 InnoDB存储引擎 14 InnoDB存储引擎 14.1 InnoDB说明 14.1.1 InnoDB作为默认存储引擎 14.1.1.1 存储引擎的趋势 14.1.1.2 InnoDB变成默认 ...
- 干货!MySQL 的 InnoDB 存储引擎是怎么设计的?
MySQL 里还有什么其他成员呢? 对于 MySQL,要记住.或者要放在你随时可以找到的地方的两张图,一张是 MySQL 架构图,另一张则是 InnoDB 架构图: 遇到问题,或者学习到新知识点时,就 ...
- MySQL数据库和InnoDB存储引擎文件
参数文件 当MySQL示例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等.在默认情况下,MySQL实例会按照一定 ...
- 在MySQL的InnoDB存储引擎中count(*)函数的优化
写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵.实践是检验 ...
- MySQL InnoDB存储引擎
200 ? "200px" : this.width)!important;} --> 介绍 本篇文章是对Innodb存储引擎的概念进行一个整体的概括,innodb存储引擎的 ...
- myisam、innodb存储引擎比较
MYSQL表类型(存储引擎) 1.概述 MySQL数据库其中一个特性是它的存储引擎是插件式的.用户可以根据应用需要选择存储引擎.Mysql默认支持多种存储引擎,以适用各种不同的应用需要.默认情况下,创 ...
- Galera集群server.cnf参数调整--Innodb存储引擎内存相关参数(一)
在innodb引擎中,内存的组成主要有三部分:缓冲池(buffer pool),重做日志缓存(redo log buffer),额外的内存池(additional memory pool).
- innodb 存储引擎特性
使用独立表空间后,系统表空间存储什么内容呢? 1.innodb 数据字典信息 和存储引擎相关. frm 是服务器的数据字典和存储引擎无关. 2. undo 回滚段. 可以单独存储. ...
- MySQL内核:InnoDB存储引擎 卷1
MySQL内核:InnoDB存储引擎卷1(MySQL领域Oracle ACE专家力作,众多MySQL Oracle ACE力捧,深入MySQL数据库内核源码分析,InnoDB内核开发与优化必备宝典) ...
随机推荐
- Sketch & UI & PS
Sketch & UI & PS app ui https://sketchapp.com/learn https://www.sketch.com/docs/ https://ske ...
- Travis CI in Action
Travis CI in Action node.js https://docs.travis-ci.com/user/tutorial/ https://docs.travis-ci.com/use ...
- how to convert SVG shapes to polygon
how to convert SVG shapes to polygon 如何将 svg 的 rect 转换成 polygon rect.circle.ellipse.line.polyline.po ...
- PAUL ADAMS ARCHITECT:爱丁堡的房屋价值创历史新高
近日,英国知名房产公司保罗·亚当斯公司根据一组调查报告表示,今年第三季度,爱丁堡的房价再创历史新高,并向大家分析了原因. 保罗·亚当斯公司(公司编号:07635831)是英国一家著名的房地产公司,总部 ...
- C++算法代码——Tuna
这道题像个水题啊,可是在我做的这个OJ上就十几人做出来-- 题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=2084 题目描述 渔民抓住 ...
- list 打乱排序
public IList<T> RandomSortList<T>(List<T> ListT) { Random random = new Random(); L ...
- DisplayFormat属性
DataFormatString="{0:格式字符串}" 在DataFormatString 中的 {0} 表示数据本身,而在冒号后面的格式字符串代表所们希望数据显示的格式: 数字 ...
- 运行maven遇到的坑,差点崩溃了。
参考链接1:https://blog.csdn.net/lch_cn/article/details/8225448/ 参考链接2:https://jingyan.baidu.com/article/ ...
- Win10下ctrl与alt键互换
我之前尝试过用第三方软件修改,但是总是不成功,后来发现直接去修改注册表也不麻烦,记录一下步骤. win + r 输入 regedit 进到这个路径 点击Keyboard Layout 右键,新建一个 ...
- Codeforces 682C Alyona and the Tree
题目链接:http://codeforces.com/problemset/problem/682/C 分析:存图,用dfs跑一遍,详细见注释 1 #include<iostream> 2 ...