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


为什么要有区?

​ 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. 匿名Lambda函数,C++

    1 // To Compile and Run: g++ -std=c++11 lambda.cc -Wall -O3 && ./a.out 2 3 4 #include <io ...

  2. jmeter性能测试小小实践

    一.测试步骤 测试计划 / 线程组 / http请求 / 监听器 / 运行脚本 / 查看报告 二.线程组 线程组:虚拟用户数 ramp up period:设置虚拟用户数需要多长的时间全部启动,如果线 ...

  3. vue引入多个指令文件

    单个指令引入,在main.js(入口JS文件)中引入你已经写好的指令文件,可以省略文件后缀: // main.js import focus from 'xxx/directive'多个指令引入 Vu ...

  4. npm安装时加 --save和不加的区别

    npm install xxx --save 命令是安装模块到项目node_modules目录下,会将模块依赖写入package.json文件中的dependencies{}下.如果将node_mod ...

  5. 汇编程序 - TD调试

    为了写这个Blog,无奈的我深夜打开虚拟机,希望也能帮助一些人,因为好像真的有人不会欸!(→_→) 写在前面的话: 1. TD面板下的调试十分重要.可以观察内存(GOTO DS:XXXX)存放的位置与 ...

  6. idea乱码

    第一步:修改intellij idea配置文件: 找到intellij idea安装目录,bin文件夹下面idea64.exe.vmoptions和idea.exe.vmoptions这两个文件,分别 ...

  7. vitrualbox虚拟机搭建

    参考:https://blog.csdn.net/weixin_45115705/article/details/100661644?depth_1-utm_source=distribute.pc_ ...

  8. PHP文件及运行(适合PHP初学者)

    PHP文件可包含HTML.JavaScript代码和 PHP代码,换句话说PHP 代码可以嵌入HTML文档.PHP文件名以php为后缀. PHP代码以"<?php"开头,以& ...

  9. 痞子衡嵌入式:我当选了2019年度官方论坛i.MXRT板块的顶级贡献者

    痞子衡桌上有一个联邦快递公司件,放了近一个月了,是同事代领的,痞子衡一直没有拆开.今天心血来潮,决定拆开瞧一瞧,这一拆就拆出了一天的好心情. 原来快递里面是一件i.MXRT产品纪念T-shirt,还有 ...

  10. Mybatis数据库驱动

    Mybatis数据库驱动 最近在学习mybatis的源码,有一个databaseIdProvider根据不同数据库执行不同sql的功能,我正好有一个mysql还有一个瀚高数据库,就去试了一下,使用如下 ...