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


为什么要有区?

​ 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. 获取n位数m进制的随机数 js

    js 获取n位数m进制的随机数 n 的取值范围为 0 < n > 1.7976931348623157e+308 (Number.MAX_VALUE) m的取值范围为 2 <= m ...

  2. 洛谷 P2105 K皇后 题解

    START: 2021-08-06 16:34:44 题目链接: https://www.luogu.com.cn/problem/P2105 题目详情: 小 Z 最近捡到了一个棋盘,他想在棋盘上摆放 ...

  3. CMMI的软件工程13-16章读书笔记

    一.软件测试   软件测试是为了发现程序中的错误而执行的过程.测试只能证明软件有错,而不能保证软件程序没错. 1. 软件版本 Alpha版 公司内测版本 Beta版 对外公测版本 发布版 正式发布版本 ...

  4. C# 高精度定时器

    https://blog.gkarch.com/2015/09/high-resolution-timer.html https://www.cnblogs.com/samgk/articles/57 ...

  5. Edge 访问网站强制HTTPS

    edge://net-internals/#hsts 1)開啟Edge chromium 瀏覽器,輸入edge://net-internals/#hsts,開啟設定介面2)找到 Delete doma ...

  6. linux 安装 jupyter notebook

    虚拟机使用的是ubuntu系统 直接遇见一个问题 E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/dpkg/ ...

  7. 虚拟机文件丢失,虚拟机无法启动,通过xx-flat.vmdk和xx-delta.vmdk恢复虚拟机

    突然掉电,导致虚拟机文件夹里面的文件丢失,只剩余-flat.vmdk和-delta.vmdk文件,其他文件全部丢失,文件格式原本为"文件"格式.新建虚拟机无法直接使用此文件夹里面的 ...

  8. mysql 8.0.30 忘记密码登录mysql:

    mysql 8.0.30 忘记密码登录mysql: cmd(使用管理员运行)-切换到mysql的bin目录下:一.输入命令:net stop mysql 停止服务: 二.输入命令:mysqld --c ...

  9. git-bash打开自动执行某条命令的快捷方式创建

    "C:\Program Files\Git\git-bash.exe" -c "npm run dev" 创建一个快捷方式,在目标里面加上以上参数,然后运行. ...

  10. axios utils axios.postForm

    npm install axios -S 目录 ajax.js   请求工具 /* ajax请求函数模块 返回值: promise对象(异步返回的数据是: response.data) */ impo ...