您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

MySQL:InnoDB的页合并与页分裂到底是什么

时间:2023-12-27 13:11:54  来源:微信公众号  作者:陆队长
不管是页分裂还是页合并,InnoDB都会在索引树上加写锁(x-latch)。在操作频繁的系统中这会是在隐患,可能会导致索引的锁竞争(index latch contention)。如果表中没有合并和分裂操作(也就是写操作),称之为“乐观(optimistic)”更新,只需要使用读锁(S)。带有合并或者分裂的操作称之为“悲观(pessimistic)”更新,使用写锁(X)。​

本文为摘录文章,如有错误,请指正。文章是以MySQL5.7版本进行说明,和现有版本可能会有一定差距,但是数据页的设计基本没有发生过变化,因此,可以作为学习参考。原文为2017年发表的一篇文章:《InnoDB Page Merging and Page Splitting - Percona Database Performance Blog》。

1 文件表(File-Table)结构

在MySQL5.7创建windmills库(schema)和wmills表,在文件目录(/var/lib/mysql)有如下内容:

data/
  windmills/
      wmills.ibd
      wmills.frm

原因是从MySQL5.6开始innodb_file_per_table参数默认设置为1,即:每个表都会单独作为一个文件存储(如果有分区,可能有多个文件)。如果配置为0,则所有的表都是写入公共表空间。

  • vmills.ibd文件由多个段(segments)组成,每个段和一个索引有关;
  • 段由多个区构成,区仅存于段内,每个区的默认固定大小为1MB(页体积默认情况下);
  • 区是由很多数据页构成,默认大小为16KB,即一个分区最多由64个数据页构成。
  • 数据页可以容纳2-N行数据行,行的数量取决于数据行的大小;InnoDB要求页至少要有两行,因此行的大小最多为8000bytes。
  • 文件的结构不会随着数据行的删除而变化,但是段会跟着区的变化而变化;

MySQL:InnoDB的页合并与页分裂到底是什么图片

2 根、分支和叶子(Roots,Branches and Leaves)

每个页(逻辑上指的是主键索引的叶子节点)包含2-N行数据行,根据主键排列,树有着特殊的页区管理不同的分支,即内部节点(INodes)。示例如下:

MySQL:InnoDB的页合并与页分裂到底是什么图片

ROOT NODE #3: 4 records, 68 bytes
 NODE POINTER RECORD ≥ (id=2) → #197
 INTERNAL NODE #197: 464 records, 7888 bytes
 NODE POINTER RECORD ≥ (id=2) → #5
 LEAF NODE #5: 57 records, 7524 bytes
 RECORD: (id=2) → (uuid="884e471c-0e82-11e7-8bf6-08002734ed50", millid=139, kwatts_s=1956, date="2017-05-01", locatinotallow="For beauty's pattern to succeeding men.Yet do thy", active=1, time="2017-03-21 22:05:45", strrecordtype="Wit")

表结构为:

CREATE TABLE `wmills` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `uuid` char(36) COLLATE utf8_bin NOT NULL,
  `millid` smallint(6) NOT NULL,
  `kwatts_s` int(11) NOT NULL,
  `date` date NOT NULL,
  `location` varchar(50) COLLATE utf8_bin DEFAULT NULL,
  `active` tinyint(2) NOT NULL DEFAULT '1',
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `strrecordtype` char(3) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_millid` (`millid`)
) ENGINE=InnoDB;

B+树的根节点就是查询的根节点,如图的#3就是根节点。根节点(页)包含了索引ID、INodes数量等信息。INodes页包含了关于页本身的信息、值的范围等。最后还有叶子节点,存储着具体的数据行的全部数据。在示例中,叶子节点#5有57行记录,共7524bytes。这行信息是具体的记录,可以看到数据行内容。

因此, 使用InnoDB管理表和行,InnoDB会将数据以分支、页和记录形式进行组织。InnoDB可操的最小粒度是页,页加载进内存后才会通过扫描页获取行数据(即示例中的record)。

3 页的内部原理(page internals)

数据页的数据会按照主键的顺序来排序,这也是我们在设计表主键时设置为AUTO_INCREMENT的原因,这样在频繁插入时,写入的数据尽可能的写入相同的页,写满后刷盘也可以是顺序写。

MySQL:InnoDB的页合并与页分裂到底是什么图片

但是如果页的数据比较小,就会导致磁盘和内存空间的浪费,因此,如果 页的数据大小/页大小 小于一定比例,就会做页合并,这个值我们称之为MERGE_THRESHOLD,默认值为50%。

MySQL:InnoDB的页合并与页分裂到底是什么图片

当本页数据写满后,就会从内存中申请新页(next)进行写入。

MySQL:InnoDB的页合并与页分裂到底是什么图片

每个叶子节点都有着一个指向包含下一条(顺序)记录的页的指针,这也是InnoDB可以实现自顶向下的遍历和叶子节点顺序范围扫描的能力基础。

4 页合并(page merging)

当执行数据行删除时,并没有物理删除,而是将改行数据标记(flaged)为删除,允许被其他记录声明使用。

MySQL:InnoDB的页合并与页分裂到底是什么图片

当页中删除的记录达到MERGE_THRESHOLD(默认页体积的50%),InnoDB确认最靠近的前后页是否页达到MERGE_THRESHOLD,如果也已经在限定值之下, 可以将两个页进行合并优化空间使用。如上图,当page#5数据小于50%时,由于page#6数据量也是小于50%,因此会进行页合并,合并后,page#6就会变为空页,可以接纳新数据。

MySQL:InnoDB的页合并与页分裂到底是什么图片

MySQL:InnoDB的页合并与页分裂到底是什么图片

在delete/update语句操作中都可能会诱发页合并的发生,关联到当前页的相邻页。如果页合并成功,在INFOMATION_SCHEMA.INNODB_METRICS中的index_page_merge_successful将会增加。

5 页分裂(Page Splits)

假设有如下场景,page#10已经被填满时,继续插入数据,#10没有足够空间去容纳新的记录,根据“下一页”逻辑,记录应该由page#11负责,但是页#11也已经满了。

MySQL:InnoDB的页合并与页分裂到底是什么图片

MySQL:InnoDB的页合并与页分裂到底是什么图片

这时候的简化逻辑为:

  1. 创建新页#12;
  2. 判断当前页(page#10)可以从哪里进行分裂(记录行里面);
  3. 移动记录行;
  4. 重新定义页与页之间的关系;

MySQL:InnoDB的页合并与页分裂到底是什么图片

新的页#12被创建。

MySQL:InnoDB的页合并与页分裂到底是什么图片

此时的页与页之间的关系为:

  • Page #10 will have Prev=9 and Next=12
  • Page #12 Prev=10 and Next=11
  • Page #11 Prev=12 and Next=13(page#13是后续顺序插入新增的页);

这样,B+树水平方向的逻辑一致性仍然满足,但是在物理存储上页可能是乱序的,大概率会落到不同的区。

不太清楚这里是否会有疑问,page#10和page#11虽然都已经写满,但是可能已经存在page#12,并且还有大量剩余空间,为什么不做数据迁移呢?这样不就可以不插入新页而导致大量的空间浪费了吗?

虽然从理论上是可行的,但是在实操中,这时候InnoDB就需要先遍历确认next page是否有空余位置,甚至是继续遍历直至找到有空余位置的页,然后进行数据迁移,这个操作可能带来大量遍历的时间复杂度以及数据复制的IO操作,因此,方案不可行。

因此,我们可以总结:页分裂可能发生在执行插入或者更新时,但是可能也会造成页的错位(dislocation),即落入不同的区。

InnoDB用INFORMATION_SCHEMA.INNODB_METRICS表来跟踪页的分裂数。可以查看其中的index_page_splits和index_page_reorg_attempts/successful统计。

当page#12和page#10的数据都低于MERGE_THRESHOLD时,这时候可以通过页合并将数据合并回来。

另一种方式是使用OPTIMIZE重新整理表,可以将大量分布在不同区的页理顺,因此,也是一个很重量级和耗时的过程。

同时,不管是页分裂还是页合并,InnoDB都会在索引树上加写锁(x-latch)。在操作频繁的系统中这会是在隐患,可能会导致索引的锁竞争(index latch contention)。如果表中没有合并和分裂操作(也就是写操作),称之为“乐观(optimistic)”更新,只需要使用读锁(S)。带有合并或者分裂的操作称之为“悲观(pessimistic)”更新,使用写锁(X)。



Tags:   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
访问网站显示不安全是什么原因?怎么解决?
访问网站时显示“不安全”,主要原因以及解决办法: 1.没用HTTPS加密:网站还在用老的HTTP协议,数据传输没加密,容易被人偷看或篡改。解决办法是网站管理员启用HTTPS,也就是给网站装...【详细内容】
2024-04-08  Search: MySQL  点击:(3)  评论:(0)  加入收藏
掌握独立站SEO策略,提升网站流量与排名
图片来源:https://guangxianchuangan.cn/在当今数字化时代,拥有一个独立网站对于企业和个人而言至关重要。然而,仅仅拥有一个网站是不够的,关键在于如何让更多的人发现并访问您...【详细内容】
2024-04-08  Search: MySQL  点击:(4)  评论:(0)  加入收藏
快手蓝色小钥匙跳转微信的流程介绍
自从快手主页挂载风潮在去年刮过之后,大众的好奇心与探索欲望犹如潮水般滚滚而来,不曾减退。近期,小钥匙跳转功能的崭露头角,更是引起了广泛关注。我时常收到询问,如何驾驭这一神...【详细内容】
2024-04-08  Search: MySQL  点击:(2)  评论:(0)  加入收藏
微信朋友圈如何置顶
智能手机的时代,微信作为一款广受欢迎的社交软件,朋友圈是微信的核心功能之一。在微信朋友圈中,有些信息对于小伙伴们来说非常重要,为了方便自己和朋友找到可以选择置顶,置顶后自...【详细内容】
2024-04-08  Search: MySQL  点击:(2)  评论:(0)  加入收藏
Facebook新用户扩展怎么做?
Facebook 是一个社交网站,可让您轻松地与家人和朋友在线联系和分享,截至目前,已经有100个国家都在使用Facebook聊天交友,用户群体非常庞大。Facebook营销,作为我们拓展新客户中不...【详细内容】
2024-04-08  Search: MySQL  点击:(3)  评论:(0)  加入收藏
详解微信里面的分期可以提现吗?可以在哪里使用
微信作为一款广泛使用的社交软件,不仅提供了聊天、朋友圈分享等基础功能,还融合了支付、购物、金融等多种服务。其中,微信分期作为一种便捷的金融服务,受到了许多用户的青睐。那...【详细内容】
2024-04-08  Search: MySQL  点击:(3)  评论:(0)  加入收藏
微信表情包更新:原创设计师带来全新风格!
随着社交网络的不断发展,表情包已经成为了人们日常沟通中不可或缺的一部分。微信作为中国最受欢迎的即时通讯工具之一,其表情包更是广受欢迎,为用户提供了丰富多彩的表情选择。...【详细内容】
2024-04-08  Search: MySQL  点击:(6)  评论:(0)  加入收藏
微信朋友圈功能大改版:社交互动更丰富更有趣!
在数字社交时代,微信朋友圈已成为人们分享生活点滴、交流感情心情的重要平台。然而,随着社交需求的不断升级和用户体验的不断追求,微信朋友圈近日进行了一次重大改版,引入了一系...【详细内容】
2024-04-08  Search: MySQL  点击:(5)  评论:(0)  加入收藏
探索微信的隐秘特性及其高效的使用技巧
探索微信的创意分享功能,让朋友圈的动态不再单调。无论是想要讲述一个故事,还是分享一段难忘的回忆,微信都为你提供了丰富的编辑工具,让你的视频和照片充满个性和情感。┘视频添...【详细内容】
2024-04-08  Search: MySQL  点击:(4)  评论:(0)  加入收藏
优化手机配置,轻松实现照片和视频的自动文字标注功能
在数字时代,我们不仅追求照片和视频的高清晰度,更希望能够让这些视觉内容“说话”,即通过文字来传达更多的信息和情感。幸运的是,通过一些简单的手机设置,我们可以让发布的照片和...【详细内容】
2024-04-08  Search: MySQL  点击:(3)  评论:(0)  加入收藏
▌简易百科推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  爱可生开源社区    Tags:MySQL   点击:(5)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  爱可生开源社区  微信公众号  Tags:MySQL   点击:(10)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  MySQL学习  微信公众号  Tags:MySQL   点击:(8)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  字节跳动技术团队    Tags:ByteHouse   点击:(23)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10    dbaplus社群  Tags:MySQL   点击:(5)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  转转技术  微信公众号  Tags:MySQL   点击:(26)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  数据库干货铺  微信公众号  Tags:MySQL   点击:(41)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  编程技术汇    Tags:MySQL   点击:(50)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  数据库干货铺  微信公众号  Tags:MySQL   点击:(53)  评论:(0)  加入收藏
mysql索引失效的场景
MySQL中索引失效是指数据库查询时无法有效利用索引,这可能导致查询性能显著下降。以下是一些常见的MySQL索引失效的场景:1.使用非前导列进行查询: 假设有一个复合索引 (A, B)。...【详细内容】
2024-01-15  小王爱编程  今日头条  Tags:mysql索引   点击:(82)  评论:(0)  加入收藏
站内最新
站内热门
站内头条