MySQL(十)表空间结构:区、段与碎片区
表空间结构:区、段与碎片区
为什么要有区?
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(十)表空间结构:区、段与碎片区的更多相关文章
- 判断mysql数据库表和表字段是否存在
1.判断数据库表是否存在, // mysqlSELECT table_name FROM information_schema.tables WHERE table_name=#{tableName, ...
- MySQL表结构,表空间,段,区,页,MVCC
索引组织表(IOT表):为什么引入索引组织表,好处在那里,组织结构特点是什么,如何创建,创建IOT的限制LIMIT. IOT是以索引的方式存储的表,表的记录存储在索引中,索引即是数据,索引的KEY为P ...
- MySQL表结构,表空间,段,区,页,MVCC ,undo 事务槽
索引组织表(IOT表):为什么引入索引组织表,好处在那里,组织结构特点是什么,如何创建,创建IOT的限制LIMIT. IOT是以索引的方式存储的表,表的记录存储在索引中,索引即是数据,索引的KEY为P ...
- mysql向表中某字段后追加一段字符串:
mysql向表中某字段后追加一段字符串:update table_name set field=CONCAT(field,'',str) mysql 向表中某字段前加字符串update table_n ...
- Oracle表空间、段、区和块简述
本文转载自:http://blog.itpub.net/17203031/viewspace-682003/ 在Oracle学习过程中,存储结构,表段区块可能是每个初学者都要涉及到的概念.表空间.段. ...
- ORACLE体系结构一 (逻辑结构)-表空间、段、区和数据块
一.Oracle的逻辑结构 Oracle的逻辑结构是一种层次结构.主要由:表空间.段.区和数据块等概念组成.逻辑结构是面向用户的,用户使用Oracle开发应用程序使用的就是逻辑结构.数据库存储层次结构 ...
- ORACLE体系结构逻辑结构-表空间、段、区和数据块
转自: https://www.cnblogs.com/sunziying/p/8994792.html 一.Oracle的逻辑结构 Oracle的逻辑结构是一种层次结构.主要由:表空间.段.区和数据 ...
- mysql向表中某字段前后追加一段字符串 concat(), trim(), ltrim(), rtrim(), repeat()
1.mysql向表中某字段后面追加一段字符串:update table_name set field=CONCAT(field, '分隔符', str);//'分隔符',可以为空,也可以省略updat ...
- 第二百七十八节,MySQL数据库-表内容操作
MySQL数据库-表内容操作 1.表内容增加 insert into 表 (列名,列名...) values (值,值,值...); 添加表内容添加一条数据 insert into 表 (列名,列名. ...
- 详解MySQL大表优化方案( 转)
当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...
随机推荐
- 简单了解promise
promise是什么: JavaScript中存在很多异步操作, Promise将异步操作队列化,按照期望的顺序执行,返回 符合预期的结果.可以通过链式调用多个 Promise达到我们的目的. Pro ...
- [Cisco] Policy Based Routing
在某些情況下,會希望指定特定的來源及目的走特定的出口,卻又不是全部的網段都希望套用,這時就可以透過PBR來達成這個需求. 如以下拓樸 1.1.1.0/24的網路往5.5.5.0的封包需要指定e0/1當 ...
- Spyglass CDC工具使用(四)
最近一直在搞CDC (clock domain crossing) 方面的事情,现在就CDC的一些知识点进行总结. 做CDC检查使用的是Spyglass工具.以下内容转载自:Spyglass之CDC检 ...
- 在VMWare里安装Win11虚机
1. 安装win11有最低硬件要求 64位CPU双核,内存4G,硬盘64G,受信任的平台模块(TPM)2.0,支持UEFI安全启动 2. VMware新建虚机的设置 1)创建64位虚拟机,CPU设置为 ...
- 2019.11.14 typeScript环境搭建
当前环境为windows系统,在VSCode下搭建typeScript环境.在mac系统下同window系统一样,只是安装好ts环境后可能会报tsc命令不能使用的错误,这个时候需要找到tsc命令所在的 ...
- Abaqus:单位、高清图片
参考: https://blog.csdn.net/Rayyyy/article/details/113798490 Abaqus高清图片: https://jingyan.baidu.com/art ...
- linux修改用户密码期限
1. https://www.cnblogs.com/wwwcf1982603555/p/15474557.html 设置密码复杂度: http://events.jianshu.io/p/533d3 ...
- 1--我们写了一个java类,那么生成一个对象占用多大的内存?
public class Student { private long id; private long userId; private byte state; private long create ...
- scala apply方法和update方法
示例代码1 class TestApplyClass { def apply(param: String): String = { println("apply method called, ...
- 一个小数据库SQLite
参考 https://blog.csdn.net/csdnhsh/article/details/93376733 https://www.runoob.com/sqlite/sqlite-creat ...