【MySQL】InnoDB

结构图

在这里插入图片描述

内存

Buffer Pool 数据缓冲

对于数据的操作,不是每次都直接操作磁盘,因为磁盘的速度太慢了。 InnoDB使用了一种缓冲池的技术,也就是把磁盘读到的页放到一块内存区域里面。这个内存区域就叫Buffer Pool

  1. InnoDB操作数据有一个最小的逻辑单位,叫做页(索引页和数据页,占16KB),Buffer Pool缓存的是就是他们。
  2. 读取页先判断是不是在缓冲池里面,如果是,就直接读取,不用再次访问磁盘。
  3. 修改数据先修改缓冲池里面的页。
  4. InnoDB里面有专门的后台线程把Buffer Pool的数据写入到磁盘
  5. 默认大小是128M
  6. LRU算法来管理缓冲池

Change Pool写缓冲

当需要更新一个数据页时,如果数据页在BufferPool中存在,那么就直接更新好了。否则的话就需要从磁盘加载到内存,再对内存的数据页进行操作。也就是说,如果没有命中缓冲池,至少要产生一次磁盘IO;如果这个数据页不是唯一索引,不存在数据重复的情况,也就不需要从磁盘加载索引页判断数据是不是重复(唯一性检查)。这种情况下可以先把修改记录在Change Buffer中,从而提升更新语句(Insert、Delete、Update)的执行速度

  1. 把 Change Buffer 记录到数据页的操作叫做 merge
  2. 什么时候发生 merge?在访问这个数据页的时候,或者通过后台线程、或者数据库shut down、redo log写满时触发
  3. change buffer 用的是 buffer pool 里的内存,可以通过参数 innodb_change_buffer_max_size 来动态设置
  4. change buffer 只限于用在普通索引的场景下,而不适用于唯一索引。在实际使用中,普通索引和 change buffer 的配合使用,对于数据量大的表的更新优化还是很明显的
  5. 对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。这种业务模型常见的就是账单类、日志类的系统

Adaptive Hash Index

对于一些热点数据页,InnoDB会自动建立自适应Hash索引,也就是在B+Tree索引基础上建立Hash索引,这个过程对于客户端是不可控制的,隐式的

redo log(重做日志)

如果在内存中(Buffer Pool)把数据改了,还没来得及落磁盘,而此时的数据库挂了怎么办?如果每个请求都需要将数据立马落磁盘之后,那速度会很慢,MySQL可能也顶不住

  1. 记录的是“在某个数据页上做了什么修改”。当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做,然后才删除log
  2. redo log 是循环写的,空间固定会用完,此时停止更新,强制刷新log到磁盘。这种日志和磁盘配合的整个过程,其实就是 MySQL 里的 WAL 技术(Write-Ahead Logging),它的关键点就是先写日志,再写磁盘
  3. 当然redo log也不是每一次都直接写入磁盘,在Buffer Pool里面有一块内存区域(Log Buffer)专门用来保存即将要写入日志文件的数据,默认16M,它一样可以节省磁盘IO
  4. 刷盘时间:
    在这里插入图片描述
    0 延时写 :logbuffer 将每秒一次地写入 logfile 中,并且 logfile 的 flush 操作同时进行。 该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。
    1(默认,实时写,实时刷) :每次事务提交时 MySQL 都会把 logbuffer 的数据写入 logfile,并且刷到磁盘 中去。
    2(实时写,延 迟刷):每次事务提交时 MySQL 都会把 logbuffer 的数据写入 logfile。但是 flush 操 作并不会同时进行。该模式下,MySQL 会每秒执行一次 flush 操作。
  5. 作用:保证即使数据库发生异常重启,之前提交的记录都不会丢
  6. 如一条更新操作,如果内存数据页中已经存在该数据则直接更新数据页,redoLog会增加一条日志记录;如果不在内存数据页中,则在Change Buffer中记录一条要往某数据页更新的log,同时redoLog也会新增一条Change Bufer要往某数据页更新的log,redolog记录普通数据页的改动和changebuffer的改动

磁盘

system tablespace 系统表空间

由内部系统表组成,存储表和索引的元数据

双写缓冲区

  1. InnoDB的页和操作系统的页大小不一致,InnoDB页大小一般为16K,操作系统页大小为4K,InnoDB的页写入到磁盘时,一个页需要分4次写
  2. 如果宕机导致页本身损坏,用redo log来做崩溃恢复是没有意义的。所以在对于应用redolog之前,需要一个页的副本。如果出现了写入失效,就用页的副本来还原这个页,然后再应用redolog。这个页的副本就是double write,InnoDB的双写技术。通过它实现了数据页的可靠性。
  3. 跟redo log 一样,double write 由两部分组成,一部分是内存的double write,一个部分是磁盘上的doublewrite。因为doublewrite是顺序写入的,不会带来很大的开销

file-per-table tablespaces 独占表空间

开启后,则每张表会开辟一个表空间,存放表的索引和数据

general tablespaces 通用表空间

可以创建一个通用的表空间,用来存储不同数据库的表

temporary tablespaces 临时表空间

存储临时表的数据,包括用户创建的临时表,和磁盘的内部临时表

Redo log

undo log tablespace

undolog(撤销日志或回滚日志)记录了事务发生之前的数据状态(不包括select) ,如果修改数据时出现异常,可以用undo log来实现回滚操作(保持原子性)。

和redo log的交互

  1. 事务开始,从内存或磁盘取到这条数据,返回给Server 的执行器;
  2. 执行器修改这一行数据的值为penyuyan;
  3. 记录name=qingshan到undo log;
  4. 调用存储引擎接口,在内存(Buffer Pool)中修改 name=penyuyan;
  5. 记录name=penyuyan到redo log;
  6. 事务提交。

存储

每张InnoDB 的表有两个文件(.frm和.ibd)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值