MySQL进阶二(InnoDB存储引擎)

大纲

  1. 存储引擎介绍
  2. MySQL架构与内部模块
  3. innoDB的磁盘结构与内存结构

继续上一篇,我们在得到执行计划之后,sql是不是就可以执行了?这里有两个问题:
1.数据存放在哪里?或者说放在一个什么结构里面
2.执行计划在哪里执行,怎么执行?

1.存储引擎的基本介绍

我们先来看第一个问题,在关系型数据库中,数据是存放在表中,我们可以把这个表理解成Excel里面的表格,所以我们在存储数据时还要组织数据的存储结构,这个存储结构就是由我们的存储引擎决定的,在MySQL里面,支持多种存储引擎,存储引擎是以插件的形式存在,那么这些存储引擎的差别在哪里呢?

1.1存储引擎比较

常见的存储引擎
  innoDB和MyISAM是我们用的最多的两个存储引擎,在MySQL5.5之前,默认的存储引擎是MyISAM,它是MySQL自带的。
  MyISAM前身是ISAM(Indexed Sequential Access Method:利用索引,顺序存取数据的方法)。
  MySQL5.5之后默认的存储引擎改成了innoDB,主要是因为InnoDB支持事务,支持行级锁,对于业务一致性的要求高的场景来说更合适。


如果需要一个用于查询的临时表,可以用memory,顾名思义就是存在于内存中的表,访问速度会很快。
具体各个存储引擎的特性:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html

1.2.执行引擎

第二个问题,执行计划就是由执行引擎去操作存储引擎的,不同的存储引擎实现了相同的API,因此对于执行引擎来说,不同的存储引擎的操作是一样的。

2.MySQL体系架构总结
2.1模块详解

Connectors:用来支持各种语言和SQL的交互,比如PHP,Java等。
management Service&utililties:系统管理和控制工具,包括备份恢复,MySQL复制,集群等。
connection pool:连接池,管理需要缓冲的资源,包括用户密码权限线程等。
sql interface:用来接收客户端的sql命令,并返回结果。
parser:用来解析sql语句。
optimizer:查询优化器。
cache & buffers:查询缓存,还有表缓存,key缓存,权限缓存等。
pluggable storage engines:插件式存储引擎,提供api给服务层使用。

2.2架构分层
3.一条更新SQL是如何执行的?

基本流程和查询SQL是一致的,解析器-》优化器-》执行引擎,主要的区别在于拿到符合条件的数据之后的操作。

3.1缓冲池 Buffer Pool

  首先,innoDB的数据都是存储在磁盘中的,innoDB操作数据有一个最小单元,叫做(索引页和数据页)。我们对数据的操作,不是每次都直接操作磁盘,这样太慢了。innnoDB使用了一种缓冲池的技术,也即是把磁盘读到的每一页放到一块内存里面,这个区域就叫做Buffer Pool
  每次读取页的时候,先从缓存池中读取,如果缓存池中存在就直接读取,不再访问磁盘。
  修改数据的时候,先修改缓存池里的页。当磁盘和缓存池里的页数据不一致的时候,我们把它叫做脏页。InnoDB会有专门的线程,把buffer pool的数据写入到磁盘,每隔一段时间就把多个修改写入磁盘,这个动作就叫刷脏

3.2.InnoDB的内存和磁盘结构:https://dev.mysql.com/doc/refman/5.7/en/innodb-architecture.html
InnoDB Architecture
3.2.1.内存结构

1. Buffer Pool
 Buffer Pool缓存的是页信息,包括索引页和数据页,默认大小是128M(134217728字节),可以调整。当缓存池满了的时候,使用LRU算法来管理缓存池(链表实现,不是传统的LRU,分成了young和old),经过淘汰的数据之后剩下的就是热点数据。
2. change Buffer 写缓存
  在更新缓存的时候,如果在缓存中没有数据,就要从磁盘读取一次数据到缓存再更新,至少会发生一次io,所以为了避免这种情况,增加了一块change Buffer,如果这个数据页不是唯一索引,不需要考虑数据唯一性(否则就还是要跟磁盘的数据作比较,避免不了io操作),这种情况下可以先把修改记录在缓冲池中,从而提升语句(insert update delete)的执行速度。最后把Change Buffer 记录到数据页的操作叫merge,什么时候发生merge:在访问这个数据页的时候、或者通过后台线程、或者数据库shut down、redo log写满时触发。
  如果数据大部分索引时非唯一索引,并且业务时写多读少,不会在数据写后立即读取,就可以调大一点Change Buffer,默认是占Buffer Pool的25%。
3.Log Buffer(redo Log)
  如果buffer pool的脏页还没有刷新到磁盘时,数据库宕机或者重启,这些数据丢失。如果写到一半,甚至会破坏数据文件导致数据不可用。为了避免这个问题,innoDB把所有的写操作专门写入到一个日志文件,并且在数据库启动时从这个文件进行恢复操作(实现crash-safe)-用来实现事务的持久性。
  这个文件就是磁盘的redo Log,对应于/var/lib/mysql/目录下的ib_logfile0和ib_logfile1,每个大小48M
  这种日志和磁盘的配合过程,其实就是MySQL里面的WAL(Write Ahead Log),先写日志,再写磁盘。
  这里还有个知识点,写redo Log到磁盘是顺序IO,写数据到磁盘是随机io,所以写日志的速度更快。
  redo log buffer写入到磁盘的时机有3种选择,首先我们知道,内存往磁盘写数据中间时存在操作系统缓存的,flush就是把os cache刷到磁盘中。
show variables like 'innodb_flush_log_trx_commit'
默认是1,含义:https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit



总结一下redo Log的特点:

  1. redo Log是innoDB存储引擎实现的,不是所有存储引擎都有实现
  2. redo Log记录的是物理日志,不是记录每一行数据改了之后的状态,是记录数据页的改动。
  3. redo Log的大小是固定的,前面写的内容会被覆盖。


    图片.png

    checkpoint是当前要覆盖的位置。如果writepos跟checkpoint重叠,说明redo
    log已经写满,这时候需要同步redo log到磁盘中。

3.2.2.磁盘结构

  表空间可以看作是innoDB存储引擎逻辑层最高层,所有的数据都存放在表空间中。InnoDB的表空间分为5大类。
系统表空间 system table space
  主要包含双写缓冲,change buffer,undo log,如果没有指定file-per-table,也会包含用户创建的表。

  1. undo log(撤销日志或回滚日志)记录了事务发生之前的数据状态。
    如果修改数据时出现异常,可以用undo log来实现回滚操作(保持原子性)。
    在执行undo 的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,属于逻辑格式的日志。
    redo Log和undo Log与事务密切相关,统称为事务日志。
  2. 数据字典:由内部系统表组成,存储表和索引的元数据(定义信息)。
  3. 双写缓冲(InnoDB的一大特性):
    InnoDB的页和操作系统的页大小不一致,InnoDB页大小一般为16K,操作系统页大小为4K,InnoDB的页写入到磁盘时,一个页需要分4次写。

    如果存储引擎正在写入页的数据到磁盘时发生了宕机,可能出现页只写了一部分的情况,比如只写了4K,就宕机了,这种情况叫做部分写失效(partialpagewrite),可能会导致数据丢失。尽管我们已经有了redo log但是如果这个页已经损坏,那再恢复也是没意义的,因此我们应用redo log之前需要一个页的副本,如果出现了页的写入失效,则先还原这个页再应用redo log。这个页的副本就是double write,双写技术,通过它保证数据页的可靠性。
    有了这些日志之后,我们来总结一下一个更新操作的流程,这是一个简化的过程。
    name原值是qingshan。
    updateusersetname='penyuyan'whereid=1;
    1、事务开始,从内存或磁盘取到这条数据,返回给Server 的执行器;
    2、执行器修改这一行数据的值为penyuyan;
    3、记录name=qingshan到undo log;
    4、记录name=penyuyan到redo log;
    5、调用存储引擎接口,在内存(Buffer Pool)中修改 name=penyuyan;
    6、事务提交。
3.3.Binlog日志

  binlog以事件的形式记录了所有的DDL和DML语句(因为它记录的是操作而不是数据值,属于逻辑日志),可以用来做主从复制和数据恢复。
  跟redo log不一样,它的文件内容是可以追加的,没有固定大小限制。
  在开启了binlog功能的情况下,我们可以把binlog导出成SQL语句,把所有的操作重放一遍,来实现数据的恢复。
  binlog的另一个功能就是用来实现主从复制,它的原理就是从服务器读取主服务器的binlog,然后执行一遍。
有了这两个日志之后,我们来看一下一条更新语句是怎么执行的:


整体流程

1、先查询到这条数据,如果有缓存,也会用到缓存。
2、把name改成盆鱼宴,然后调用引擎的API接口,写入这一行数据到内存,同时记录redo log。这时 redo log 进入prepare 状态,然后告诉执行器,执行完成了,可以随时提交。
3、 执行器收到通知后记录binlog,然后调用存储引擎接口, 设置redolog为commit状态。
4、更新完成。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容