表空间结构:区、段与碎片区


为什么要有区?

​ B+树中的每一层的页都会形成一个双向链表,双向链表之间的物理位置可能会离得非常远,当遇到范围查询的适用场景的时候,就会定位到最左边和最右边的记录,然后沿着双向链表一直扫描,而如果这其中的两个页面物理上离得特别远,就会成为随机I/O,由于磁盘和内存的速度相差了几个数量级(磁盘寻道、半圈旋转、数据传输),因此随机I/O的速度是非常慢的,所以应该尽量让链表中逻辑上相邻的页物理上也相邻,这样进行范围查询的时候就可以使用顺序I/O。

为了尽量让链表中逻辑上相邻的页物理上也相邻,因此引入区的概念,一个区就是物理上连续的64个页,即64*16=1MB。并且在数据量较大的时候,会以区为单位为索引分配空间而不是以页为基本单位,甚至数据特多多的时候,会一次性分配多个连续的区,虽然可能造成空间浪费,但是消除了很多的随机I/O,大大地提高了性能。

为什么要有段?

范围查询实际上是对叶子节点进行的顺序扫描,因此如果把叶子节点和非叶子节点都放到申请到的区的话,进行范围扫描的效果就大打折扣了,因此InnoDB对叶子结点和非叶子节点进行了区分,各自有各自的区,存放叶子节点或者非叶子节点的区就被称作是一个段(即按照功能划分),因此一个索引会产生两个段,一个是叶子节点段,一个是非叶子节点段。

​ 常见的段有数据段索引段回滚段,数据段即是B+树中的叶子节点段,索引段则是非叶子节点段。

​ 在InnoDB存储引擎中,对段的管理都是引擎自身完成的,简化了DBA对于段的管理。

段并不是物理上连续的区,而是一个逻辑的概念,由若干个零散的页面和一些完整的区组成的。

为什么要有碎片区?

​ 默认情况下,一个使用InnoDB存储引擎的表只有一个聚簇索引,一个索引会生成两个段,而段则是以区为单位申请存储空间的,一个区占用1M,所以默认情况下一个只存储了几个记录的小表也会占用2M的存储空间,以后每添加一个索引就会再申请2M,这显然是不合理的。

​ 因此便引入了碎片区:在一个碎片区中,并不是所有的页都是为了存储同一个段的数据而存在,而是碎片页中的页可以用于不同的目的,即一些可以用于段A、另一些可以用于段B,甚至有些页那个段都不属于碎片区直属于表空间,并不属于任何一个段

​ 所以从此之后为每个段分配存储空间的策略是这样的:

  • 在刚开始插入数据的时候,段是从某个碎片区以单个页面为单位来分配存储空间的
  • 当某个段占用了32个碎片区页面(即半个区)的时候,就会申请以完整的区为单位来分配存储空间

​ 所以上面介绍区的时候才说:“段并不是物理上连续的区,而是一个逻辑的概念,由若干个零散的页面和一些完整的区组成的”

区的分类:

​ 区大致可以分为4类:

  • 空闲区:没有用过区中的任何页面
  • 有剩余空间的碎片区:
  • 没有有剩余空间的碎片区:
  • 附属于某个段的区:即索引的叶子节点区和非叶子节点区


表空间

​ 表空间可以看做是InnoDB存储引擎逻辑结构的最高级,所有的数据都存放在表空间里面。

​ 表空间是一个逻辑容器,表空间的存储对象是段,在一个表空间中可以有一个或多个段,但是每一个段只能属于一个表空间,表空间数据库由一个或者多个段组成,表空间从管理上可以分为:系统表空间独立表空间撤销表空间临时表空间

独立表空间

  • 每一张表都有一个独立的表空间,也就是数据和索引都存放在自己的表空间中。独立的表空间(即单表)可以在不同的数据库之间迁移。

  • 独立表空间的空间可以回收(DROP TABLE可以,其他情况则不能自动回收)。对于统计分析或者是日志表,删除大量数据之后可以通过:ALTER TABLE TableName engine=innodb;回收不用的空间。

  • 独立表空间的空间结构由段、区、页组成。

  • 真实表空间对应的文件大小:在数据目录中,一个新建表的ibd文件在5.0中占用了96K(6个页),在8.0中则占用了112K(7页,一页存储的是表结构)

查看InnoDB的表空间类型:
show variables like 'innodb_file_per_table'

​ 开启意味着每一张表都会单独保存为一个ibd文件。

系统表空间

​ 系统表空间和独立表空间类似,只不过整个MySQL进程只有一个系统表空间,在系统表空间中会额外存储一些有关整个系统信息的页面,这部分是独立表空间中没有的。

InnoDB数据字典

​ 这个内部系统表,就是数据字典,系统内部表不允许用户直接访问,但是提供了information_schema数据库中以innodb_sys开头的表以供参考,存储引起启动的时候,会首先读取这些以sys开头的系统表,然后填充到这些以InnoDB_sys开头的表中

MySQL(十)表空间结构:区、段与碎片区的更多相关文章

  1. 判断mysql数据库表和表字段是否存在

    1.判断数据库表是否存在, // mysqlSELECT table_name FROM information_schema.tables WHERE table_name=#{tableName, ...

  2. MySQL表结构,表空间,段,区,页,MVCC

    索引组织表(IOT表):为什么引入索引组织表,好处在那里,组织结构特点是什么,如何创建,创建IOT的限制LIMIT. IOT是以索引的方式存储的表,表的记录存储在索引中,索引即是数据,索引的KEY为P ...

  3. MySQL表结构,表空间,段,区,页,MVCC ,undo 事务槽

    索引组织表(IOT表):为什么引入索引组织表,好处在那里,组织结构特点是什么,如何创建,创建IOT的限制LIMIT. IOT是以索引的方式存储的表,表的记录存储在索引中,索引即是数据,索引的KEY为P ...

  4. mysql向表中某字段后追加一段字符串:

    mysql向表中某字段后追加一段字符串:update table_name set field=CONCAT(field,'',str) mysql 向表中某字段前加字符串update table_n ...

  5. Oracle表空间、段、区和块简述

    本文转载自:http://blog.itpub.net/17203031/viewspace-682003/ 在Oracle学习过程中,存储结构,表段区块可能是每个初学者都要涉及到的概念.表空间.段. ...

  6. ORACLE体系结构一 (逻辑结构)-表空间、段、区和数据块

    一.Oracle的逻辑结构 Oracle的逻辑结构是一种层次结构.主要由:表空间.段.区和数据块等概念组成.逻辑结构是面向用户的,用户使用Oracle开发应用程序使用的就是逻辑结构.数据库存储层次结构 ...

  7. ORACLE体系结构逻辑结构-表空间、段、区和数据块

    转自: https://www.cnblogs.com/sunziying/p/8994792.html 一.Oracle的逻辑结构 Oracle的逻辑结构是一种层次结构.主要由:表空间.段.区和数据 ...

  8. mysql向表中某字段前后追加一段字符串 concat(), trim(), ltrim(), rtrim(), repeat()

    1.mysql向表中某字段后面追加一段字符串:update table_name set field=CONCAT(field, '分隔符', str);//'分隔符',可以为空,也可以省略updat ...

  9. 第二百七十八节,MySQL数据库-表内容操作

    MySQL数据库-表内容操作 1.表内容增加 insert into 表 (列名,列名...) values (值,值,值...); 添加表内容添加一条数据 insert into 表 (列名,列名. ...

  10. 详解MySQL大表优化方案( 转)

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

随机推荐

  1. Ajax属性

    如何创建一个 Ajax <script>         window.onload=function(){             1)创建一个异步调用对象             va ...

  2. Quartus II 18.x Modelsim仿真设置

    Quartus II 18.x Modelsim仿真设置 本节内容介绍在如何在QuartusII 应用环境下设置modelsim仿真选项,并进行波形仿真.下面以四位乘法器为例介绍. 在QuartusI ...

  3. api进阶Day1文件的创建、删除、访问、设置过滤器并查询。目录的删除、创建。

    文件的创建: package file; import java.io.File; import java.io.IOException; /* create:创建 new:新 file:文件 使用F ...

  4. jmeter 变量的使用

    jmeter添加变量 一.添加用户自定义变量 添加用户自定义变量 作用:常用数据参数化.当变量发生变化时,不需要逐个脚本修改,只需要修改用户自定义中的变量就可以了. 变量使用如下图 二.函数助手定义变 ...

  5. 移动服务(f[i] [j] [k],这三个人,位置为a[i],j,k的最小价值)

    移动服务(f[i] [j] [k],这三个人,位置为a[i],j,k的最小价值) 题意 给出点之间到达价值,使用3个人处理一个序列,f[i] [j] [k],这三个人,每次处理序列中一个值,三个人中一 ...

  6. STM32F103使用FSMC对接正点原子3.5寸TFTLCD屏幕

    fsmc的使用算是32里面有点绕的一个知识点,但是想明白了其实也没啥了. 首先我先放32个0在这儿: 0000  0000  0000  0000  0000  0000  0000  0000 [3 ...

  7. C/C++命名规范-C语言基础

    这一篇文章想要介绍的是编写代码的时候业界比较常用的一些命名规范,以及个人平时的一些命名规范.涉及"驼峰命名法"."下划线命名法"."帕斯卡命名法&qu ...

  8. C++ 全面总结

    1. 基本数据类型:没什么好说的.知道浮点数存储起来不精确.各种类型占的大小在不同平台可能不一样就行了 2. 初始化列表:能用就用.能防止潜在的类型收窄, 3. static_cast 和 dynam ...

  9. QT网络编程【一】

    1.QUdpSocket头文件无法识别怎么解决? 问题原因:qmake没有添加network的模块.在工程配置文件中添加配置即可. 2.选择c++的socket库还是QUdpSocket? 3.同样的 ...

  10. ARM-linux的Windows交叉编译环境搭建

    交叉编译Arm Linux平台的QT5库 1.准备交叉编译环境 环境说明:Windows10 64位 此过程需要: (1)Qt库开源代码,我使用的是5.13.0版本: (2)Perl语言环境5.12版 ...