《MySQL系列-InnoDB引擎25》表-InnoDB逻辑存储结构

InnoDB逻辑存储结构
从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称为块(block),InnoDB存储引擎的逻辑存储结构大致如下。

1 表空间
表空间可以看做是InnoDB存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。在默认情况下InnoDB存储引擎有一个共享表空间ibdata1,即所有数据都存放在这个表空间内。如果用户启用了参数innodb_file_per_table,则每张表的数据可以单独放到一个表空间内。
如果启用了innodb_file_per_table的参数,需要注意的是每张表的表空间内存放的只是数据、索引和插入缓存Bitmap页,其他类的数据,如回滚(undo)信息,插入缓存索引页、系统事务信息,二次写缓存(Double write buffer)等还是存放在原来的共享表空间内。
可以使用py_innodb_page_info小工具,来查看表空间中各页的类型和信息。在使用时需要注意的是,总共有三个文件,分别是include.py、mylib.py、py_innodb_page_info.py,放在同一目录即可。
GitHub下载
# 1.python文件
[root@zxy_master py_innodb_page_type]# ll
total 12
-rw-r--r-- 1 root root 1257 Feb 23 10:06 include.py
-rw-r--r-- 1 root root 2179 Feb 23 10:07 mylib.py
-rw-r--r-- 1 root root 234 Feb 23 09:59 py_innodb_page_info.py# 2.表空间统计查看
[root@zxy_master py_innodb_page_type]# python py_innodb_page_info.py /var/lib/mysql/ibdata1
# 总页数
Total number of page: 4864:
# 插入缓存
Insert Buffer Bitmap: 1
# 系统页
System Page: 123
# 事务系统页
Transaction system Page: 2
# 可用页
Freshly Allocated Page: 4326
# Undo页
Undo Log Page: 288
# segment节点页
File Segment inode: 8
# 数据页
B-tree Node: 114
# 表空间标题页
File Space Header: 2# 3.详细表空间内容查看
[root@zxy_master py_innodb_page_type]# python -v py_innodb_page_info.py /var/lib/mysql/ibdata1
......
2 段
表空间是由各个段组成,常见的段有数据段、索引段、回滚段等。
其中,leaf node segment是B+树的叶子节点,即数据段。Non-leaf node segment是B+树的非索引节点,即索引段。Roolback segment是回滚段。
在InnoDB引擎中,对段的管理都是由引擎自身所完成的,DBA不能也没有必要对其进行控制。这和Oracle对数据库中自动段的管理(ASSM)类似,从一定程度上简化了DBA对段的管理。

3 区
区由连续页组成的空间,在任何情况下每个区的大小都为1MB。为保证页的连续性,InnoDB存储引擎一次从磁盘申请4-5个区。在默认情况下,InnoDB存储引擎的页大小为16KB,即一个区共有64个连续的页。
在InnoDB 1.2.x版本新增参数innodb_page_size后,通过该参数可以将默认页的大小设置为4K、8K,但是页中的数据库不是压缩。这时区中的页的数量通用页为256、128。总之,不论页的大小怎么变化,区的大小总是1M。
mysql> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.00 sec)
当启用参数innodb_file_per_table后,创建的表默认是96KB。
这时就引起了思考?
一个区有64个页,一个页16KB,那么创建的表至少应该是1MB才对?为什么这里创建的表才96KB。
# 1.为方便测试,t2字段类型为varchar(7000),能保证一个页最多存放2条记录
mysql> create table page_test(-> t1 int not null auto_increment,-> t2 varchar(7000),-> primary key (t1)-> ) engine=innodb;
Query OK, 0 rows affected (0.04 sec)# 2.通过查看表空间文件,可以发现初始表空间大小默认96KB
mysql> system ls -lh /var/lib/mysql/zxy/page_test.ibd
-rw-r----- 1 mysql mysql 96K Feb 23 11:00 /var/lib/mysql/zxy/page_test.ibd
其实是每个段开始时,先用32个页大小的碎片页(fragement page)来存放数据,在使用完这些页后才开始64个连续页的申请。这样做的目的是对于一些小表,或者是undo这类的段,可以在开始申请较少的空间,节省磁盘容量的开销。
测试一:插入两条数据,表空间大小、B+树变化
结论1:经过测试发现表大小未发生变化
# 1.插入第一条
mysql> insert into page_test select null,repeat('a',7000);
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0# 2.插入第二条
mysql> insert into page_test select null,repeat('a',7000);
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0# 3.查看大小
mysql> system ls -lh /var/lib/mysql/zxy/page_test.ibd
-rw-r----- 1 mysql mysql 96K Feb 23 11:26 /var/lib/mysql/zxy/page_test.ibd
结论2:
通过py_innodb_page_info.py工具,参数-v查看表空间详情。可以看到page offset是3的页,这个是数据页。page level表示所在索引层,0表示叶子节点。因为两条数据未满16KB,所以当前所有记录都在一个页中,因此没有非叶节点。但是如果再插入一条数据,就会产生非叶节点。
[root@zxy_master py_innodb_page_type]# python py_innodb_page_info.py -v /var/lib/mysql/zxy/page_test.ibd
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0000>
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 6:
Freshly Allocated Page: 2
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 1
File Segment inode: 1
测试二:再次插入一条数据后,表空间大小、B+树变化
结论1:经过测试发现表大小未发生变化
mysql> insert into page_test select null,repeat('a',7000);
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0mysql> system ls -lh /var/lib/mysql/zxy/page_test.ibd
-rw-r----- 1 mysql mysql 96K Feb 23 11:34 /var/lib/mysql/zxy/page_test.ibd
结论2:可以看到page offset为3的页的page level由之前的0变为了1,这时虽然新增的记录导致了B+树的分裂操作,但这个页的类型还是B-tree Node。
[root@zxy_master py_innodb_page_type]# python py_innodb_page_info.py -v /var/lib/mysql/zxy/page_test.ibd
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0001>
page offset 00000004, page type <B-tree Node>, page level <0000>
page offset 00000005, page type <B-tree Node>, page level <0000>
Total number of page: 6:
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 3
File Segment inode: 1
测试三:再次插入60条数据后,表空间大小、B+树变化
结论1:表空间大小变化
mysql> DELIMITER &&mysql> create procedure load_t1(count int unsigned)-> begin-> declare s int unsigned default 1;-> declare c varchar(7000) default repeat('a',7000);-> while s <= count DO-> insert into page_test select null,c;-> set s = s+1;-> end while;-> end;-> &&
Query OK, 0 rows affected (0.01 sec)mysql> delimiter ;mysql> call load_t1(60);
Query OK, 1 row affected (0.67 sec)# 可以看到现在有63条数据后,表空间的大小还是小于1MB,即表示数据空间的申请还是通过碎片页,而不是通过64个连续页的区。
mysql> system ls -lh /var/lib/mysql/zxy/page_test.ibd;
-rw-r----- 1 mysql mysql 592K Feb 23 13:50 /var/lib/mysql/zxy/page_test.ibd
结论2:
可以观察到,B-tree Node页一共有33个,除去一个page level为1的非叶节点,一共有32个page level为0的页,也就是说,对于数据段,已经有32个碎片页了。之后如果再申请空间,肯定就是按照64个页大小进行增长了。
[root@zxy_master py_innodb_page_type]# python py_innodb_page_info.py -v /var/lib/mysql/zxy/page_test.ibd
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0001>
page offset 00000004, page type <B-tree Node>, page level <0000>
page offset 00000005, page type <B-tree Node>, page level <0000>
page offset 00000006, page type <B-tree Node>, page level <0000>
page offset 00000007, page type <B-tree Node>, page level <0000>
page offset 00000008, page type <B-tree Node>, page level <0000>
page offset 00000009, page type <B-tree Node>, page level <0000>
page offset 0000000a, page type <B-tree Node>, page level <0000>
page offset 0000000b, page type <B-tree Node>, page level <0000>
page offset 0000000c, page type <B-tree Node>, page level <0000>
page offset 0000000d, page type <B-tree Node>, page level <0000>
page offset 0000000e, page type <B-tree Node>, page level <0000>
page offset 0000000f, page type <B-tree Node>, page level <0000>
page offset 00000010, page type <B-tree Node>, page level <0000>
page offset 00000011, page type <B-tree Node>, page level <0000>
page offset 00000012, page type <B-tree Node>, page level <0000>
page offset 00000013, page type <B-tree Node>, page level <0000>
page offset 00000014, page type <B-tree Node>, page level <0000>
page offset 00000015, page type <B-tree Node>, page level <0000>
page offset 00000016, page type <B-tree Node>, page level <0000>
page offset 00000017, page type <B-tree Node>, page level <0000>
page offset 00000018, page type <B-tree Node>, page level <0000>
page offset 00000019, page type <B-tree Node>, page level <0000>
page offset 0000001a, page type <B-tree Node>, page level <0000>
page offset 0000001b, page type <B-tree Node>, page level <0000>
page offset 0000001c, page type <B-tree Node>, page level <0000>
page offset 0000001d, page type <B-tree Node>, page level <0000>
page offset 0000001e, page type <B-tree Node>, page level <0000>
page offset 0000001f, page type <B-tree Node>, page level <0000>
page offset 00000020, page type <B-tree Node>, page level <0000>
page offset 00000021, page type <B-tree Node>, page level <0000>
page offset 00000022, page type <B-tree Node>, page level <0000>
page offset 00000023, page type <B-tree Node>, page level <0000>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 37:
Freshly Allocated Page: 1
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 33
File Segment inode: 1
测试四:继续插入60条数据后,表空间大小、B+树变化
结论1:表空间大小增加明细
mysql> call load_t1(60);
Query OK, 1 row affected (0.68 sec)mysql> system ls -lh /var/lib/mysql/zxy/page_test.ibd;
-rw-r----- 1 mysql mysql 9.0M Feb 23 13:59 /var/lib/mysql/zxy/page_test.ibd
结论2:出现较多freshly allocated page空闲页。
[root@zxy_master py_innodb_page_type]# python py_innodb_page_info.py -v /var/lib/mysql/zxy/page_test.ibd
.......
Total number of page: 576:
Freshly Allocated Page: 510
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 63
File Segment inode: 1
4 页
同大多数数据库一样,InnoDB有页(Page)的概念(也可以称为块),页是InnoDB磁盘管理的最小单位。在InnoDB存储引擎中,默认每个页的大小为16KB。从InnoDB 1.2.x版本开始,可以通过参数innodb_page_size将页的大小设置为4K、8K、16K。若设置完成,则所有表中页的大小都为innodb_page_size,不可以对其进行再次修改。除非通过mysqldump导入和导出操作产生新的库。
在InnoDB存储引擎中,常见的页类型有:
- 数据页(B-tree Node)
- undo页 (undo log Page)
- 系统页(System Page)
- 事务数据页(Transcation system Page)
- 插入缓存位图页(Insert Buffer Bitmap)
- 插入缓存空闲列表页(Insert Buffer Free List)
- 未压缩的二进制大对象页(Uncompressed BLOB Page)
- 压缩的二进制大对象页(compressed BLOB Page)
5 行
InnoDB存储引擎是面向列的,也就是说数据是按行存放的。每个页存放的行记录也是有硬性定义的饿,最多存放16KB/2-200行的记录。
每页最少存储2行记录,用链表连接气力啊,否则会失去B+树的意义。数据大的行记录,如:大字符串、TEXT、BLOB对象,都是采用行溢出数据存储。不同的行格式、存储方式不同。
相关文章:
《MySQL系列-InnoDB引擎25》表-InnoDB逻辑存储结构
InnoDB逻辑存储结构 从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称为块(block),InnoDB存储引擎的逻辑存储结构…...
YOLOv8之C2f模块——与YOLOv5的C3模块对比
一、源码对比 YOLOv8完整工程代码下载:ultralytics/ultralytic C2f模块源码在ultralytics/nn/modules.py下,源码如下: class C2f(nn.Module):# CSP Bottleneck with 2 convolutionsdef __init__(self, c1, c2, n1, shortcutFalse, g1, e…...
动态规划实例——换零钱的方法数(C++详解版)
原写了 Java 版本的如何求解换钱的方法数,近期进行了一些细节上的补充,以及部分错误更正,将语言换为了 C 语言。 基础题目 假设你现在拥有不限量的 1 元、5 元、10 元面值纸币,路人甲希望找你换一些零钱,路人甲拿出的…...
linux c
射频驱动 管理硬件设备、分配系统资源 内核由中断服务程序 调度程序 内存管理程序 网络和进程间进程通信程序 linux支持动态加载内核模块 支持多处理smp机制 内核可以抢占preemptive linux系统拥有多个发行版,可能由一个组织 公司和个人发行 VGA兼容或者更…...
第十三章 系统错误消息 - 一般系统错误消息 S - Z
文章目录第十三章 系统错误消息 - 一般系统错误消息 S - Z第十三章 系统错误消息 - 一般系统错误消息 S - Z 错误代码描述<SUBSCRIPT>下标值不合法或Global引用过长。<SWIZZLE FAIL>打开了一个oref,然后试图在另一个无法引用的相关对象中进行搅拌。这可…...
移动web基础
初始缩小:布局视口大于视觉视口 初始放大:布局视口小于视觉视口 布局视口等于视觉视口(这种动作行为叫做理想视口) <meta name"viewport" content"width375" /> <meta name"viewport"…...
MyBatis和MyBatis_Plus有什么区别【面试常考题】
MyBatis和MyBatis_Plus的区别 MyBatis_Plus MyBatis_Plus 是一个 MyBatis 的增强工具,只是在 MyBatis 的基础上增强了却没有做改变,MyBatis-Plus支持所有MyBatis原生的特性,所有引入MyBatis-Plus不会对现有的MyBatis框架产生任何影响。 MyBa…...
华为OD机试用Python实现 -【统一限载货物数最小值】(2023-Q1 新题)
华为OD机试题 华为OD机试300题大纲统一限载货物数最小值题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现算法逻辑华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查…...
Vue入门小练习
文章目录Hello VueVue文本指令Vue属性绑定Vue双向绑定Vue事件绑定Vue猜数字Vue简单计算器Vue简单计算器升级版Vue循环遍历Vue员工列表练习Vue小练习Vue显示隐藏相关使用一些简单的小案例来熟悉Vue的基本使用方法 Hello Vue <!DOCTYPE html> <html lang"en"…...
Oracle-09-集合运算符篇
2022年4月13日23:01:25 通过本章学习,您将可以:1、描述 SET 操作符2、将多个查询用 SET 操作符连接组成一个新的查询目录 🏆一、SET OPERATORS ⭐️1.1、UNION /UNION ALL ⭐️1.2、INSTERSECT ⭐️1.3、MINUS dz...
获取浏览器(服务端)请求中特定的Cookie
有必要解释一下HttpServletRequest接口,因为我们需要从它里面获取Cookie。 HttpServletRequest HttpServletRequest是一个Java接口,提供了访问HTTP请求信息的方法,例如HTTP方法、请求URI、头部、参数和会话属性。它是Java Servlet API的一部…...
c++11 标准模板(STL)(std::unordered_set)(九)
定义于头文件 <unordered_set>template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templat…...
python实战应用讲解-【实战应用篇】文件操作(附python示例代码)
目录 知识储备 使用 python-libarchive-c 模块 创建压缩文件 解压文件 查看信息...
OpenCV-Python系列(二)—— 图像处理(灰度图、二值化、边缘检测、高斯模糊、轮廓检测)
一、【灰度图、二值化】 import cv2 img cv2.imread("lz2.png") gray_img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图 # 二值化,(127,255)为阈值 retval,bit_img cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY) cv2.imshow(photo1,im…...
ccc-台大林轩田机器学习基石-hw1
文章目录Question1-14Question15-PLAQuestion16-PLA平均迭代次数Question17-不同迭代系数的PLAQuestion18-Pocket_PLAQuestion19-PLA的错误率Question20-修改Pocket_PLA迭代次数Question1-14 对于有明确公式和定义的不需要使用到ml 智能系统在与环境的连续互动中学习最优行为策…...
hadoop03-MapReduce【尚硅谷】
大数据学习笔记 MapReduce 一、MapReduce概述 MapReduce是一个分布式运算程序的编程框架,是基于Hadoop的数据分析计算的核心框架。 MapReduce处理过程为两个阶段:Map和Reduce。 Map负责把一个任务分解成多个任务;Reduce负责把分解后多任务处…...
测牛学堂:软件测试python学习之异常处理
python的捕获异常 程序在运行时,如果python解释器遇到一个错误,则会停止程序的执行,并且提示一些错误信息,这就是异常。 程序停止执行并且提示错误信息,称之为抛出异常。 因为程序遇到错误会停止执行,有时…...
图神经网络--图神经网络
图神经网络 图神经网络图神经网络一、PageRank简介1.1互联网的图表示1.2PageRank算法概述1.3求解PageRank二、代码实战2.1引入库2.2加载数据,并构建图2.3计算每个节点PageRank重要度2.4用节点尺寸可视化PageRank值一、PageRank简介 PageRank是Google最早的搜索引擎…...
React useCallback如何使其性能最大化?
前言 React中最让人畅谈的就是其带来的灵活性,可以说写起来非常的舒服。但是也就是它的灵活性太强,往往让我们忽略了很多细节的地方,而就是这些细节的东西能进行优化,减小我们的性能开销。可以说刚学React和工作几年后写React的代…...
长尾关键词使用方法,通过什么方式挖掘长尾关键词?
当你在搜索引擎的搜索栏中输入有关如何使用长尾关键词的查询时,你可能希望有简单快捷的方式出现在搜索结果中,可以帮助你更好地应用seo。 不过,这里要记住一件事:SEO 策略只会为你的网站带来流量;在你的产品良好之前&a…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
若依项目部署--传统架构--未完待续
若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加,传统开发模式存在效率低,重复劳动多等问题。若依项目通过整合主流技术框架&…...
后端下载限速(redis记录实时并发,bucket4j动态限速)
✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制(动态)✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 🧩 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…...
