MySQL 是怎样运行的(二)——数据库文件系统


title: MySQL 是怎样运行的(二)——数据库文件系统
date: 2019-3-18 12:34:39
tags: [mysql]
categories: 掘金小册
keywords: mysql
photos:


MySQL 是怎样运行的(二)——数据库文件系统

查看数据目录:SHOW VARIABLES LIKE 'datadir';
区分mysql安装目录数据目录

表在文件系统的表示

1.表结构,存储在 表名.frm 中。
2.数据,根据引擎不同,方式不同

InnoDB的表数据存储

InnoDB其实是使用页为基本单位来管理存储空间的,默认的页大小为16KB。

对于InnoDB存储引擎来说,每个索引都对应着一棵B+树,该B+树的每个节点都是一个数据页,数据页之间不必要是物理连续的,因为数据页之间有双向链表来维护着这些页的顺序。

InnoDB的聚簇索引的叶子节点存储了完整的用户记录,也就是所谓的索引即数据,数据即索引。

InnoDB的表空间(文件空间)

  • 是抽象的概念,对于一个或多个文件,包含若干个页,具有不同类型。
    系统表空间
  • 大小默认12M,会动态扩展,可初始修改大小。
  • 只有一份,Mysql版本5.5.7到5.6.6,数据都默认存储到系统表空间
    独立表空间
  • 5.6.6以后,InnoDB默认会给每个表单独创建独立表空间。文件名表名.ibd
  • 表名.frm存储表结构,表名.ibd存储数据和索引。
  • 可初始设置不使用独立表空间,也可将一个表的空间表示(独立↔系统)
    其他表空间
    通用表空间、undo表空间、临时表空间

MyISAM的储存表示

  • test.frm 表结构
  • test.MYD 数据文件
  • test.MYI 索引文件

视图的表示

视图是虚拟的表,一条查询的结果集。储存视图的时候是不用存数据的,只需要存储其数据结构,会被储存到对于数据库下,视图名.frm文件。

其他文件

服务器进程文件:进程id
服务器日志文件:各种日志
默认/自动生成的SSL和RSA证书和密钥文件:用于C/S通信

文件系统对DB的影响

1.DB名与TABLE名不得超过文件系统允许的最大长度
2.特殊字符:在上述两名字中,存在除数字和拉丁字母以外的所有字符,都映射成@编码值,如’test?'表会创建,‘test@003f.frm’
3.数据文件和索引文件的大小都受限于文件系统

Mysql数据库介绍

  • mysql 核心数据库,存储用户账户和权限和其他重要信息
  • information_schema 描述信息,元数据
  • performance_schema 状态信息,用于监控mysql
  • sys 通过视图结合infor_schema和perfor_schema表,用于展示

InnoDB的表空间

抽象概念,可想象成包含若干个数据页的池子

独立表空间

区(extent:程度,范围) 与 组

作用:表空间中页太多,使用便于管理

  • 页大小16kb,连续的64个页就是一个区,默认1MB
  • 每256个区(也是连续吗?)被分为一组,256MB

区

页开头

第一个组开头3个页类型是固定的,比较特殊,分别是:

  1. FSP_HDR:描述表空间的一些属性,每个表空间开头唯一的页
  2. IBUF_BITMAP: 存储本组关于INSERT BUFFER信息
  3. INODE:

除第一个组外,每个组开头有2个页类型是固定的

  1. XDES:extent descriptior,用于登记本组256个区的属性
  2. IBUF_BITMAP

区的作用:

场景:当数据量很大,页有很多的时候,N次插入后。通过双向链表连接的两个逻辑上的页,其物理距离可能相差很远。若使用范围查找,只需找到最左和最右记录,而中间的记录通过双向链表扫描,使用的是随机I/0(很慢),我们希望其物理位置也最好相邻,可使用顺序IO

区: 物理位置上连续的64个页,在数据量大的时候,分配空间按照区(1MB)分配而不是页(16KB),升至数个区的分配。(好处:减少随机I/0,坏处:空间预分配的浪费,以空间换时间)

段:存放叶子或非叶子节点 的区(和零散页)的集合
因为顺序查找,是同一层的双向链表间的查找,我们不希望 叶子节点和非叶子节点混到一起了。所以一个索引有

  • 叶子节点段 (叶子节点 区集合)
  • 非叶子节点段 (非叶子节点 区集合)

场景:若数据少,岂不是一个索引要一个区,1MB叶子段,1MB非叶子段?这么浪费?所以有了碎片区
碎片区(fragment)
一个区中,不是所有页都是为了储存同一个段。而是有的页是段A,有的是段B。

  • 在刚开始向表中插入数据的时候,段是从某个碎片区单个页面为单位来分配存储空间的。
  • 当某个段已经占用了32个碎片区页面之后,此段就会以完整的区为单位来分配空间

区的分类

  • FREE 空闲的区
  • FREE_FRAG 有剩余空间的碎片区
  • FULL_FRAG 没有剩余空间的碎片区
  • FSEG 附属于某个段的区

可以理解将碎片区理解为:放置了不同段页面的区?

XDES页 与链表

XDES

  • Segment ID :被分配给哪个段,不属于则无
  • List Node:用于表示XDES链表,记录上一或下一个区的XDES指针
  • State:标注了区的类别(四种)
  • Page State Bitmap:用于表示页的使用状态

插入数据(XDES Entry链表)

当段中数据较少时,插入过程使用的是表空间链表

  1. 查看是否有FREE_FRAG碎片区,有则插入数据
  2. 否则申请FREE空闲区,并将其状态变为碎片区
  3. 直到将碎片区变为FULL_FRAG

当段中数据已经占满32个零散的页,再使用表空间链表遍历,效率就低了,

  1. 通过段中的,FREE链表,申请完整的区(空闲区)

几种用于查找的列表

每个区的头部 都有XDES Entry,通过它能将同种类别的区连接成链表。便于查找
隶属于表空间的链表

  1. FREE链表
  2. FREE_FRAG链表
  3. FULL_FRAG链表

隶属于 段 的链表

  1. FREE链表:同一个段中的 FREE区
  2. NOT_FULL链表:同一个段中,仍然有碎片空间的区组成
  3. FULL链表:同一个段中,没有空闲空间的区组成

汇总:每个索引有两个段(叶子段,非叶子段),每个段需要三种类型页链表(FREE,NOT_FULL,FULL),另外有三个隶属于表空间的链表。

基节点:用于存放这些链表的信息(头节点位置,尾节点位置,节点数)

段的结构

段虽然是逻辑概念,但是每个段都有一个INODE Entry记录段的信息
段的结构

  • Segment ID 段号
  • NOT_FULL_N_USED 记录NOT_FULL链表中使用了多少页面,用于定位
  • 三种链表的表头
  • 魔数:用于检测初始化
  • 段中 零散的页,记录其页号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值