MySQL内存结构简析

本文有参照其他博客的地方,若有侵权请告知本人删除
参考博客:https://www.cnblogs.com/arthinking/p/13034126.html
一些指令
MySQL内存结构简析_第1张图片

DQL、DML、DDL、DCL

  • 数据查询语言DQL(select)
  • 数据操纵语言DML(update,insert,delete)
  • 数据定义语言DDL(create 表)
  • 数据控制语言DCL(commit,rollback,grant【授权】)

InnoDB架构图

官网结构图
MySQL内存结构简析_第2张图片

  • Buffer Pool 加速读
  • Change Buffer 用于非唯一索引的加速写
  • Log Buffer 用于加速redo Log写
  • Adaptive Hash Index 自适应hash索引,用于加快页的查询,InnoDB会判断当前搜索是否可以走Hash索引。【比如:模糊查询不走】
  • Operating System Cache 表示操作系统缓存
  • redo Log 用于记录写操作【写的时候先在buffer pool改变,然后将对应的sql记录在这里】【redo log是磁盘的顺序读写】
  • System Tablespace 存储一个ibdatal的文件,该文件包含
    • InnoDB Data Dictionary存储元数据,比如表结构、索引
    • Double Write Buffer 当Buffer Pool写入数据的时候会先写入这个区域,而不是直接改变元数据【由于操作系统的一页大小和InnoDB的一页大小不一致,直接写入存在MySQL服务破溃后的数据不一致的问题,但是先写入这个区就可以保证MySQL服务破溃后仍可以直接先从这里再次拿取】【关于双写缓存跟内存之间的防止MySQL服务崩溃机制,是配合redo Log去保证的,在写入这个缓存之间的redo Log都不会被清理,直到写入成功之后才允许清理,每次从元数据获取相关页的数据的时候都会先查看是否有对应的redo log,如果有就按照里面的记录去生成实时最新的数据再返回,这样保证数据的一致性】
    • Change Buffer 当Mysql shut down的时候,修改就会被存储在磁盘这里
    • Undo Logs 记录事务修改操作【修改前的样子,用于回滚】
  • File-Per-Table Tablespaces存储.ibd文件,存储数据和索引
  • General Tablespaces 共享表空间,MySQL5.7.24之后被弃用
  • Temporary Tablespaces 存储一个叫ibtmpl的文件,正常情况下启动创建时会创建临时表空间,停止时会删除临时表空间
  • Uudo Tablespaces 提供修改操作的原子性,即修改到一半的时候出现异常可以回滚,里面存储的就是修改前的数据

这里所有的前提,都是在InnoDB引擎下的

Buffer Pool

  • MySQL预先申请好的一块内存,用于作缓存

    • 黄色区域表示从磁盘复制过来的数据
    • 白色区域表示空闲区域

MySQL内存结构简析_第3张图片

  • 内部有三个链表

    • free链表,用于管理空闲区域
      • 基节点记录头尾节点,以及节点个数
      • 控制块就是存储对应的buffer pool里的空闲区域的地址
        在这里插入图片描述
    • flush链表,用于记录缓冲被修改的页(脏页)[MySQL优化会先对缓冲的页进行修改,通过另一个定时的线程,定时去修改对应的磁盘数据,当持久到磁盘之后就会提出这个脏页]
    • LRU链表,最近最少使用记录的链表【拟定:最近被访问过的,之后很有可能再被访问】,用于缓存满的时候进淘汰
      • 当第一次从磁盘取出这一页的时候,对应地址会被加入到LRU链表中,且先进的页会处于相对链表头的越后的位置
      • 当某写已有页再次被使用的时候,这个页就会被提到链表头之后,这样保证最近使用的页在前面,最后的就是过时可以被淘汰的页
    • MySQL有LRU链表优化,因为当查询一个大批量数据的时候可能导致整个buffer pool进行换血,导致一些已经缓存常用的数据被清掉,优化如下:
      • 5/8用于做热数据区域【存储常用数据缓存】,3/8相对较冷数据区域
      • 在有新增页插入冷数据区域的开头,当冷数据区域的某一个页前后访问的时间差值大于某个值的时候才会将数据迁移至热数据区
      • 为什么是大于?因为当进行全表的扫描的时候,对于表里的页的访问间隔可能很短,而全表扫描的操作本身不频繁,所以不能算这个数据属于热数据,这样才能保证热数据是真正的热数据
      • 当符合热数据之后会转入热数据区域的链表头

Change Buffer

  • 主要目的是将对二级索引的数据操作缓存下来,以此减少二级索引的随机IO,并达到操作合并的效果
  • 在MySQL5.5之前的版本中,由于只支持缓存insert操作,所以最初叫做insert buffer,只是后来的版本中支持了更多的操作类型缓存,才改叫change buffer,所以本文是基于MySQL5.5之后的版本
  • 在内存和磁盘都有,存写操作的需要改变的索引页的修改内容信息,当需要用这个索引的时候,先将磁盘里读出来的跟change buffer里的数据整合成最新的索引使用
  • 其中某个页被调用会调入buffer pool中,等到服务器空闲的时候会被刷到disk上
  • Change Buffer占用Buffer Pool的一部分,从而减少了可用于缓存数据页的内存。如果工作集几乎适合Buffer Pool,或者您的表具有相对较少的二级索引,则禁用Change Buffer可能很有用【使用innodb_change_buffering 配置参数】
    • all: InnoDB默认值,允许所有操作
    • none: 不要缓存任何操作
    • insert: 缓冲插入操作
    • deletes: 缓冲区删除标记操作
    • changes: 缓冲插入和删除标记操作
    • purges: 缓冲在后台发生的物理删除操作
  • 还可以适当调大这个区域
    • Innodb_change_buffer_max_size 变量允许将Change Buffer的最大大小配置为缓冲池总大小的百分比。默认情况下, innodb_change_buffer_max_size设置为25.最大设置为50。
  • 磁盘中还有一个change buffer主要用于,当Mysql shut down的时候,修改就会被存储在磁盘这里

Log Buffer

  • MySQL中对InnoDB表进行更改时,这些更改首先存储在InnoDB日志缓冲区的内存中,然后写入通常称为重做日志(redo logs)的InnoDB日志文件中
  • 当确认这个事物提交commit之后才会写进redo log里面,若是回滚则不存
  • 日志缓冲区大小由innodb_log_buffer_size 变量定义,默认大小为16MB

redoLog

  • 主要记录写操作的记录日志,用于异常中断的数据恢复【数据的一致性保障】

  • 由两个相同大小的存储文件ib_logfile0ib_logfile的顺序存储【连续存储的磁盘空间操作快,因为I/O只需连续访问就好】文件交替进行使用,当一个满了就换另一个,里面的内容会被覆盖,若是存在还有被操作的页(脏页),就会触发一个检查点,也就是将这些内容进行磁盘I/O,这时候会导致服务停滞一段是时间,所以这块区域越大,停滞的时间可能越长,但是频率会越低,越小则越频繁,时间越短

  • redoLog有三种系统设置,默认1,适应不同的场景MySQL内存结构简析_第4张图片

    • 0表示:不用写log buffer,只需要每秒写redo log磁盘数据一次,性能高,但会造成数据1s内的一致性问题【这一秒内突然崩溃等等情况】,适用于实时性强,一致性弱的场景,比如:论坛评论
    • 1表示:一旦事物提交,写LogBuffer,同时写入磁盘,性能最差,但一致性最强,适用于实时性弱,一致性强的场景,比如:支付场景
    • 2表示:一旦事物提交,写LogBuffer,但不立即写入磁盘,而写入操作系统的缓存(简称os buffer,会每秒调用fsync将数据刷入磁盘),适用于实时性适中,一致性适中的场景,比如:订单类

undoLog

  • 与redo log相反的东西,这个是记录数据原来的样子,用于回滚

  • 当事物出现异常中断需要回滚的时候就要用到

  • undo log主要分为两种:

    • insert undo log

      代表事务在insert新记录时产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃

    • update undo log

      事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除

binLog

  • 属于MySQL服务层面的DDL、DML记录日志,其他说明的默认是InnoDB引擎层面的
  • 主要功能是实现
    • 主从复制,从服务器拿到主服务器的bin log日志,然后执行。
    • 数据恢复,拿到某个时间段的日志,重新执行一遍

update执行顺序

在执行器中,修改数据,称为 modification

  1. modification刷入内存,Buffer PoolChange Buffer
  2. 引擎层:记录undo log (实现事务原子性)
  3. 引擎层:记录redo log (崩溃恢复使用)
  4. 服务层:记录bin log(记录DDL)
  5. 返回更新成功结果
  6. 数据等待被工作线程刷入磁盘

MySQL内存结构简析_第5张图片

你可能感兴趣的:(数据库,mysql,数据库,内存结构)