欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 数据库ALGORITHM = INSTANT研究过程

数据库ALGORITHM = INSTANT研究过程

2025/5/13 16:18:07 来源:https://blog.csdn.net/qq_41903105/article/details/147288969  浏览:    关键词:数据库ALGORITHM = INSTANT研究过程

背景


偶然在团队中发现同事大量使用 ALGORITHM = INSTANT 更新字段,根据固有的理解,平时字段的更新必然会涉及到表结构的更改,印象中数据库会加入MDL锁去保证表数据的一致性。
但是听说在Mysql8.0+特性中,表明在更新字段的时候此方法不会导致锁表,因为这是一个在线的DDL的操作方式。后续带着疑问查询了大量的文章未果,依然没有理解其中的原理,固写下文研究过程。

疑问点


例如下面的DDL方式

ALTER TABLE users ADD COLUMN age INT DEFAULT 0 COMMENT '年龄', ALGORITHM=INSTANT;

在结尾处使用了【ALGORITHM=INSTANT】的字段表述方式,即可避免锁表。

f*&!思来想去,这是什么东西,难不成是传说中的“多级&叠加表”设计?我猜想:数据依然是老数据,但是新表是新表,所以查询引擎层会append一些新表结构的字段回去。

颠覆了我的认知。

研究过程


我查询了许多文章的表述,但是最终得到的更多是【Mysql8.0+特性】。显然这样的结论并不能直接说服我们对技术的渴望,偶然看到一篇帖子,恍然大悟。
记录在淘宝的【数据库内核技术2020年3月】的报刊中,我们发现研究者对这项特性是这样描述的
在实现上,MySQL并没有在系统表中记录多个版本的schema,而是非常取巧的扩展了存储格式。在已有的info bits区域和新增的字段数量区域记录了instant column信息,instant add column之前的数据不做任何修改,之后的数据按照新格式存储。同时在系统表的private_data字段存储了instant column的默认值信息。查询时,读出的老记录只需要增加instant column默认值,新记录则按照新的存储格式进行解析,做到了新老格式的兼容。当然,这种实现方式带来的限制就是只能顺序加字段。
看完后,总结以下几点
1.在原有的数据表结构和新增的字段记录了【instant column】字段信息
2.旧数据查询的时候会补充【instant column】默认值,新数据按新的结构存储

对于大佬的总结,是根据一篇mysql的官网技术worklog来进行解读的

  • 数据库worklog-instant算法
    该技术describe 第五点有个阐述

For “old” rows, the default value will be looked up from the new
system tables and appended before return to server.

翻译过来就是:

对于“旧”行,将从新系统中查找默认值表格并在返回服务器之前附加。

这句话验证了我的猜想:表里存在的旧数据,在数据返回到服务器将新的字段进行append回去,去展示对应的完整数据行。

那也就是我们在操作数据的时候,使用了ALGORITHM = INSTANT在表里使用了DDL的方式操作,那么我们将不会关注元数据的更改情况,也就是不用关心锁表。
但是也提供了【INPLACE&FORCE 】原来的复制表的方式来更新内部表,也就是锁表的方式

  • 关于Instant算法技术内幕原理
    在这里插入图片描述

对于instant算法,可看上图

  1. 假设本身存在的一张表t1 , 先存在 a字段,插入一条数据x,此时存在了x(1) 【1 = 当前的列号情况】
  2. 现在ADD COLUMN更新表增加了b字段,再次插入一条数据y,此时存在数据x(1 + 1’) +
    y(2)。最新数据y将使用所有列的情况,而x旧数据只保存了a列的字段,并没有b的,所以需要组装返回
  3. 再次ADD
    COLUMN更新表增加了c字段,再次插入一条数据z,此时存在的数据x(1+2’)+y(2+1’)+z(3)。新增了c字段后,同上步骤,此时x将新增bc列的组装返回,y新增了c列,而x会使用所有列的情况。

表达的方式类似如图最后一张。

学习到其他大佬的对sql执行过程输出,观察到在使用instant字段后对其表进行数据新增,其新增数据会在bit字段设置为1来代表数据是instant之后的。
因为对于内部执行流程 rec_set_instant_flag_new函数在记录的Info bits字段设置REC_INFO_INSTANT_FLAG,会表示这个记录是instant add column之后创建的。

使用的注意点
1.ALGORITHM = INSTANT 不能与 LOCK 子句一起使用,如果指定了 INSTANT,并且 LOCK=NONE/SHARED/EXCLUSIVE如果同时指定了 LOCK=DEFAULT,则会引发 ER_WRONG_USAGE 错误。但是,如果同时指定了 LOCK=DEFAULT,则可以。
2.ADD COLUMN 可能会立即完成,因此我们可能不会期望立即进行 ADDCOLUMN 去修复损坏的索引
3.此工作日志不支持具有全文索引的表
4.对于 EXCHANGE PARTITION,为了简化逻辑,如果分区或要交换的表是即时的,那么该操作将被拒绝错误 ER_PARTITION_EXCHANGE_DIFFERENT_OPTION
5.对于使用它进行索引的创建或者更新,算法会被降级【ALGORITHM=INPLACE】,此时涉及到锁表,进行数据文件的物理修改
6.INPLACE 算法原理(GPT):

  1. 扫描表数据,构建索引结构。
  2. 允许并发 DML 操作(如 INSERT/UPDATE/DELETE),但某些阶段可能短暂阻塞 DDL。
  3. 最终替换旧表文件,完成索引创建

总结


使用Instant字段对元数据的操作(增加/修改字段和注释等),会将旧数据新增的字段列号只能附加在表的最后,而新数据将使用新表的数据方式存储。这是一个技术突破的东西。
仔细一看,mysql的描述感谢了Tencent的付出,腾讯哥还是厉害。他们主要的优化点是【ALTER TABLE … ADD COLUMN 可以立即完成,不需要太多的 IO 和等待时间】
这个特性的诞生,意味着大家对于新增字段大表的数据结构需要去增加字段,不会像之前那样操作锁表,mysql8.0+版本随意放心食用。

5.感谢

http://mysql.taobao.org/monthly/2020/03/01/
https://dev.mysql.com/worklog/task/?spm=a2c4e.10696291.0.0.439f19a4hwOoes&id=11250

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词