欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

InnoDB的数据结构交流

程序员文章站 2022-03-10 18:32:38
连接器由一个工作线程去从一个网络连接中读取SQL语句IO模型:IO多路复用。扩展:五种网络IO模型解析器SQL接口(SQL Interface):执行SQL语句查询解析器(Parser):对SQL语句进行拆分解析查询优化器:生成执行计划,选择最优的查询路径ps:常用定位sqlexplain sqlinformation_schema.optimizer_trace执行器:执行器根据执行计划调用存储引擎的接口innodb索引:B+树支持MVCC有效地利用以及使...

连接器

  • 由一个工作线程去从一个网络连接中读取SQL语句
  • IO模型:IO多路复用。扩展:五种网络IO模型

解析器

  • SQL接口(SQL Interface):执行SQL语句
  • 查询解析器(Parser):对SQL语句进行拆分解析
  • 查询优化器:生成执行计划,选择最优的查询路径

ps:常用定位sql

  • explain sql
  • information_schema.optimizer_trace

执行器:

  • 执行器根据执行计划调用存储引擎的接口InnoDB的数据结构交流

innodb

  • 索引:B+树
  • 支持MVCC
  • 有效地利用以及使用内存和CPU

缓存池(buffer pool)

设置属性

  • innodb_buffer_pool_size: 总容量
  • innodb_buffer_pool_instance: 缓冲池个数

缓存池里的数据结构

  • 缓存页:用来放磁盘数据页
  • hash表:缓存池缓存表,key是表空间号+数据页号, value是缓存页的地址
  • free链表:缓存池空闲表, value是缓存页元数据块
  • flush链表:将缓冲池里更新后的脏页放在链表上供后台线程更新磁盘数据时用
  • lru链表:淘汰链表,当缓存池缓存页不够时将缓存页刷到磁盘,将缓存页更新为空闲页

当一个查询sql执行时

  • 先从hash表查看缓存池中是否含有sql的缓存页信息,如果有直接从缓存池中查询返回。
  • 如果没有则从free链表获取一个空闲块的空闲页,将磁盘页加载进空闲页。从free链表剔除空闲块信息,将该数据页添加进hash表。
  • 将数据加载进lru链表冷数据区头部

当一个更新sql执行时

  • 先从hash表查看缓存池中是否含有sql的缓存页信息,如果没有就从磁盘加载进缓冲池。
  • 对需要更新的数据加索引记录锁,将原值写入undo日志。
  • 更新缓冲池里面数据(磁盘数据未修改),将更新后值命令写入redolog buffer(放redo日志的)。
  • 提交事务,将redo日志写入磁盘文件(数据还未修改), 同时写binlog日志, 最后在redo日志写commit命令。
  • 将缓存池里的缓存页加入flush链表, 后台线程异步随机将缓冲池数据刷新到磁盘
  • 刷新lru链表

redo日志提交策略(innodb_flush_log_at_trx_commit)

  • 0:提交事务不会把redo log buffer里的数据刷入磁盘文件
  • 1:提交事务必须把redo log从内存刷入到磁盘文件, 一般选择这个保证数据强一致性
  • 2: 提交事务把redo日志写入磁盘文件对应的os cache缓存里去, 可能1秒后才会把os cache里的数据写入到磁盘文件

ps:为什么还要有 redolog buffer
ps:redo日志和binlog的区别

lru预读机制和淘汰机制

  • 冷热分离:冷数据区默认37%(innodb_old_blocks_pct)
  • 冷数据区域头部的信息在1s(innodb_old_blocks_time)后访问才会挪动到热区域头部去
  • 淘汰触发时机:定时任务和加载时淘汰
    InnoDB的数据结构交流

段(segment) -> 区(extent) -> 页(page) -> 行(row)

  • extent是最小申请单位(一般申请4个),page是I/O操作的最小对象,row是data的最小单位
  • 普通表默认每个page是16K,extent的固定大小为1M(64个page)
  • 单个区上物理空间是连续的,不同区不保证连续

row的数据结构
变长字段的长度列表、NULL值列表、数据头、隐藏字段、存储信息

  • 变长字段长度列表: 十六机制, 逆序排列
  • null值列表: 二进制, 1说明是NULL, 0说明不是NULL, 逆序排列
  • 数据头: 40bit(1/2位是预留位, 3是delete_mask, 4是min_rec_mask, 5-8是n_owned,
    9-22是heap_no, 22-24是record_type, 24-40是next_record)
  • 隐藏字段: DB_ROW_ID(隐藏ID)、个DB_TRX_ID(当前事务ID)、DB_ROLL_PTR(undo日志版本号)
  • 存储信息

eg:

name age class no remark
张三 18 9 是一个男生啊啊啊

0x08 0x02 01000 0000000000000000000010000000000000011001 00000000094C 00000000032D EA000010078E 张三189是一个男生啊啊啊

row的数据头结构

  • 1-2:预留位,没任何含义
  • 3:delete_mask,标识的是这行数据是否被删除,在MySQL里删除一行数据的时候会将该标志位置为1,彻底删除(optimize table tablename)
  • 4:min_rec_mask,在B+树里每一层的非叶子节点里的最小值都有这个标记
  • 5-8:n_owned,表示当前槽管理的记录数
  • 9-22:heap_no,当前记录在当前页中的位置从2开始,0-伪记录(最小),1-虚拟记录(最大)
  • 22-24:record_type,行数据的类型,0代表的是普通类型,1代表的是B+树非叶子节点,2代表的是最小值数据,3代表的是最大值数据
  • 25-40:next_record, 下一条数据的指针(页链表),规定最小记录的下一条记录就本页中主键值最小的记录,而本页中主键值最大的记录的下一条记录就是最大记录

page的数据结构

  • 文件头(FIleHeader):38个字节,记录页的通用信息,比如上下页的页号,页类型,所有的数据页其实是一个双链表
  • 数据页头(PageHeader):56个字节, 记录本页存储记录的状态信息,如本页记录数量,槽数量
  • 最小记录和最大记录(Infimum + supremum):26个字节
  • 数据行(User Records):用来放行数据
  • 空闲空间(Free Space):存数据空间中尚未使用的区域
  • 数据页目录(Page Directory):数组,放的是主键与数据的映射关系
  • 文件尾部(File Trailer):8个字节

本文地址:https://blog.csdn.net/weixin_40682142/article/details/110843335