胡哈 发表于 2024-3-8 17:42:08

MySQL的页与行格式

什么是MySQL的页?

页是指存储引擎使用的最小的数据存储单位。
当 MySQL 执行读取或写入操作时,是以页为基本单位来进行操作的。即使读写一条数据,MySQL 也会按页操作。
MySQL 的存储引擎会将数据分成多个页,并根据需要将这些页加载到内存中进行处理。
通过使用页来组织数据,MySQL 能够更高效地管理存储空间,减少读取数据时的硬盘 I/O 次数,从而提高数据库的性能。
MySQL 页的组成?


[*]页头:页头包含了关于该页的一些元数据信息,例如页类型、页号、页大小等。页头还可能包含用于管理该页的一些控制信息。
[*]记录:记录是页中存储的实际数据内容,记录可以包含行数据、索引信息等。记录的组织方式和格式会根据具体的数据表结构和存储引擎的实现而有所不同。
[*]空闲空间:空闲空间是指页面中尚未被使用的空间,用于存放新的行数据或者在更新操作中的数据版本管理。数据库系统会动态地管理和维护空闲空间,以便高效地利用页面的存储空间。
[*]页校验和:有些数据库系统会在页中存储校验和信息,用于检测页的完整性和数据一致性。校验和可以帮助系统检测存储介质上的数据损坏或者传输过程中的错误。
[*]其他元数据:除了以上列出的内容之外,页还可能包含其他元数据信息,例如版本号、事务相关信息、锁信息等,这些信息有助于数据库系统实现事务管理、并发控制等功能。
MySQL数据为什么要存储在页上?

方便管理,提高数据的访问效率。
方便管理:通俗的理解,MySQL的页就好比一个个抽屉,数据就是放抽屉里的中药,方便对每一小块的资源进行处理。
提高数据的访问效率:MySQL可以存储大量数据,如果不存储在页上进行拆分,一次性存储在磁盘上,一次性加载几个G到内存,不是一个好的情况。
并为索引做准备,如果用B+tree作索引,想把大量的数据放入1-3层非线性的b+tree树中,若没有页来压缩归类,很难放得下。
MySQL的数据在磁盘上是紧凑的连续存储的吗?

不是。
紧凑的连续存储,舒服了强迫症工程师,但不适应磁盘。
如果是紧凑的连续存储,对表数据的头部或中间进行数据的插入、删除操作,那么后面的数据就需要移动来保证数据存储的连续性,这个过程消耗资源且无意义。
所以只需要保证逻辑上的关联就行,加个链表就能解决数据之间的关联问题。
页和索引有什么关系?

没有因果关系,但有合作关系。
没有因果体现在:页是用来存储数据,索引是用来提高查询速度的。
合作关系,体现在:MySQL加载数据是按页加载的,不是按照id一条一条加载。索引的创建,b+tree的各种节点,也是按照页来的。
默认页大小?

16KB。
MySQL 行、页、区、段、表空间什么联系?


[*]行就是一条一条的数据,并按照行格式,包含一些字段记录头的信息。
[*]多个行组合成一个页,页是指存储引擎使用的最小的数据存储单位。
[*]64个连续页组成一个区,默认一个区16KB大小,64个区刚好1MB。
[*]多个区组成一个段,段是数据库的分配单位。
[*]多个段组成一个表空间,表空间是逻辑上的存在,表空间又分为系统表空间,用户表空间,撤销表空间和临时表空间。
MySQL 行、页、区、段、表空间存在的意义是什么,解决了什么问题?


[*]行:就是一条条的数据,专门把数据放表服务于业务,没什么好说的。
[*]页:是指存储引擎使用的最小的数据存储单位,当 MySQL 执行读取或写入操作时,是以页为基本单位来进行操作的,若引擎对数据读写逐行处理,太细的粒度的读写会增加硬盘 I/O 次数,降低性能。
[*]区:区的引入有助于提高数据的连续性和存取效率。
[*]段:帮助数据库系统更好地优化存储空间的使用和数据访问的效率。
[*]表空间:通过表空间的划分和管理,可以实现对数据存储结构的灵活控制和优化。
MySQL 页的分类?


[*]数据页(Data Pages):用于存储表中的实际数据。每个数据页的默认大小是16KB,可以通过配置进行修改,其中包含着表的行记录。
[*]索引页(Index Pages):用于存储表的索引数据结构,如 B+ 树索引。每个索引页的默认大小也是16KB,可以通过配置进行修改。索引页中包含了索引节点和指向下一层节点或数据页的指针。
[*]BLOB页(Blob Pages):用于存储大型二进制对象(BLOB)数据,如图片、音频或视频文件等。BLOB 数据通常被分离存储在独立的页中,而不是与其他数据存储在同一个数据页中。
[*]Undo页(Undo Pages):用于存储事务的回滚信息,以支持事务的回滚和并发控制。Undo 页记录了旧值和未提交事务的回滚信息。
[*]插入缓冲(Insert Buffer):虽然不是一种真正的页类型,但在 InnoDB 存储引擎中使用了插入缓冲来加速数据的插入操作。插入缓冲缓存了新插入的数据,然后按顺序批量地将数据插入到数据页中
[*]系统页(System Pages):用于存储 InnoDB 存储引擎的一些系统信息,例如表空间、事务信息等。
[*]刷新(Flush)页:用于将修改过的数据页刷新到磁盘上的物理数据文件中。
[*]压缩页(Compressed Pages):用于存储使用压缩算法进行压缩的数据。
[*]重做日志页(Redo Log Pages):用于存储 InnoDB 存储引擎的重做日志(Redo Log)信息。
[*]页面链表页(Page Directory Pages):用于存储页的目录信息,帮助管理和组织其他类型的页。
[*]Page Cleaner 页(Page Cleaner Pages):用于执行后台任务,例如在 InnoDB 存储引擎中,Page Cleaner 负责回收已经使用过的数据页,以减少闲置页的数量。
[*]Free Space Info 页(Free Space Info Pages):用于跟踪数据页的空闲空间信息,帮助优化数据页的利用率。
[*]Change Buffer 页(Change Buffer Pages):用于延迟索引更新操作,在某些情况下通过 Change Buffer 缓存索引更新操作,以提高性能。
delete是真的把数据从磁盘中移除了吗?

并没有从磁盘中移除,只是标记为删除,更改了行中的元数据部分有一个叫做delete_mark的删除标记。
原因:
修改一个标志位的开销,比磁盘删除一条记录更快,当有大量数据需要删除时,如果移除磁盘数据,可能会导致所在的页为空页,删除大量的空页,仍旧是一个消耗资源的过程。。
倒不如直接软删除,当需要插入新数据时,存储引擎可以直接使用已经存在的空闲页,而不需要为新数据重新分配磁盘空间。
注意,truncate,会释放磁盘空间。
MySQL行格式有哪些?


[*]DEFAULT:这是 InnoDB 存储引擎的默认行格式。在这种格式下,数据是以紧凑的格式存储的,适合一般的 OLTP 应用。
[*]COMPRESSED:这是 InnoDB 存储引擎特有的一种行格式,在 MySQL 5.7 版本后提供。使用压缩的方式存储数据,可以减少存储空间的使用和提高性能。
DYNAMIC:InnoDB 存储引擎也支持这种行格式,适用于包含大量可变长度列的表。数据存储比较灵活,既有利于节省空间,又能提高性能。
[*]COMPACT:适用于 MyISAM 存储引擎的一种行格式,使用紧凑的格式存储数据。
[*]FIXED:适用于 MyISAM 存储引擎的另一种行格式,所有列都用固定长度存储数据。
[*]REDUNDANT:适用于 MyISAM 存储引擎的一种行格式,存储冗余信息以加快查询速度。
什么是行溢出?

行数据量超出所能容纳的最大值。
举例说明两种情况:
一个是设计表时:例如把varchar的长度设置为70000,则会报错column length too big for column 's' (max = 16383); use Blob or TEXT instea.
一个是插入或更新数据时:数据内容超过表字段约定的最大长度引发的报错(严格模式)或完整截断(非严格模式)情况。
为什么varchar行溢出显示的是max=16383,而不是65535?

因为默认的使用utf8mb4的编码(最长占4个字节)),虽然utf8编码的字符是变长,但是需要保证每个字符占最大(4个字节)字节的情况下,能够存储进去。
16383*4 = 65532,其中用2个字节用于保存字段长度(2个字节占16位,216=65536),剩余2字节无法被4整除,余下的。
页与缓冲池的关系?

真正访问页之前,需要把磁盘上的页缓存到内存中的buffer pool中,所有的变更,也是先更新缓冲池,此时并没有持久化到磁盘,称之为脏页,然后脏页通过checkpoint机制去刷盘。
为什么不采用实时刷盘策略?

磁盘比内存慢,大规模的并发读写,实时刷盘,可能导致用户改了1个字节的数据,当前页就要实时刷盘到磁盘中,极大的降低效率,如果一条SQL影响范围很大,涉及多个页,多个页不连续,又会产生随机io,所以不可实时刷盘。

来源:https://www.cnblogs.com/phpphp/p/18060293
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: MySQL的页与行格式