InnoDB表快速修改字段名方案

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

最近被问到一个问题,InnoDB表,只修改一个字段的名字,定义不修改,是否有快速方案。

这个需求的意义来源于,在表设计初期可以预留一些字段,但在预留字段投入使用时,最好能够赋予一个有意义的名字以方便使用。

复现

以下实验基于5.1.48版本。

创建一个简单表

CREATE TABLE `t` (

`c1` int(11) DEFAULT NULL,

`c2` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

插入10w条数据。将字段c2改名为c3.

mysql> alter table t change c2 c3 int(11) default null;

Query OK, 100000 rows affected (4.29 sec)

Records: 100000 Duplicates: 0 Warnings: 0

可以看到,虽然只是简单修改了字段名,在实验机器上耗时达到4.2s,显然重做了所有数据。由于这个表没有索引,数据量也比较小,如果对于更大数据的表,则需要更长的操作时间。

分析

我们知道,在

Innodb_file_per_table参数下,每个InnoDB表有两个文件t.frmt.ibd. 实际上,表字段信息只保存于t.frm。这个文件保存了表的定义信息,只有8k 仅修改字段名,实际上不需要重作数据,如果能够只对t.frm做修改,则可以加快上面这个alter语句的执行速度。

源码相关

可以想象MySQL框架中应该是调用了InnoDB引擎的某个函数,用于判断是否需要重做数据。

我们追踪一下alter table语句的执行流程,在mysql_alter_tablesql_table.cc)函数中,我们看到这个局部变量need_copy_table,它有三个可能的取值。

ALTER_TABLE_METADATA_ONLY= 0,

ALTER_TABLE_DATA_CHANGED= 1,

ALTER_TABLE_INDEX_CHANGED= 2

显然这个取值的判断结果,决定了后面的执行流程。

mysql_alter_table中调用了compare_tables用于判断alter前后的表做了多大的改动,后者在这个语句中修改了need_copy_table的值。

/* Check if changes are compatible with current handler without a copy */

if (table->file->check_if_incompatible_data(create_info, changes))

{

*need_copy_table= ALTER_TABLE_DATA_CHANGED;

DBUG_RETURN(0);

}

这个check_if_incompatitble_table的函数实现在handler/ha_innodb.cc中。这个函数的返回值可能是COMPATIBLE_DATA_NO表示表改动前后不兼容(需要重做数据)或COMPATIBLE_DATA_YES兼容(不需要重做)。

该函数有如下片段

if (check_column_being_renamed(table, NULL)) {

return COMPATIBLE_DATA_NO;

}

其实现逻辑是,如果有任何一个字段名被修改,则返回COMPATIBLE_DATA_NO

简单修改

有了上述分析,要做到快速修改表字段名,只需要把调用check_column_being_renamed的这三行注释掉即可。重新编译发布后,执行结果如下。

mysql> alter table t change c2 c3 int(11) default null;

Query OK, 0 rows affected (0.01 sec)

Records: 0 Duplicates: 0 Warnings: 0

可以看到,这回执行基本不需要时间. 对比修改前后的t.ibdMD5,没有修改,而t.frm中只是将c2的字段名改为c3,其他不变。

问题!!

这里的问题是,这个修改,是否会有副作用?虽然我们知道修改字段名应该是对数据时没有影响的,但MySQL就是这么实现了。

更深入的调查带来了“坏消息“。 MySQL 5.1.45版本中,就没有这个字段名的判断,也就是说在5.1.45中仅修改字段名是只修改frm文件的。

在新版本中特别加入的判断,是否有什么原因?这是撰写本文的意图。若有与此相关的bug或者文章说明,请回复或站内私信我。

延伸

实际上,关于这个问题,还可以继续深入,这里抛砖引玉。

1) 如果上述修改有副作用,副作用是什么,是否可以通过简单修改ibd文件,仍达到快速修改的目的?

2) 在例子中我们简单试验了修改字段名。对于varchar字段,alter table将字段长度增加,是否也可以按照上述思路快速修改?因为我们知道对于还没有数据的varchar字段长度改变,并不影响聚簇索引上的数据。 如果可行,对于预留varchar字段作为扩展来说,也是很有意义实现请看下篇。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
存储 关系型数据库 MySQL
6.2.2 【MySQL】InnoDB中的索引方案
6.2.2 【MySQL】InnoDB中的索引方案
92 0
|
24天前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
5月前
|
缓存 关系型数据库 MySQL
整体方案 参数调优 innodb_buffer_pool_size
【8月更文挑战第14天】
60 0
|
7月前
|
存储 关系型数据库 分布式数据库
PolarDB产品使用问题之如何用InnoDB引擎创建Federated表
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
65 1
|
8月前
|
存储 关系型数据库 MySQL
InnoDB中的索引方案
InnoDB中的索引方案
73 0
|
存储 关系型数据库 MySQL
MySQL使用InnoDB引擎时一张表最大可以储存数据大小为 64TB,那为什么当表中的单行数据达到16KB时,这张表只能储存一条数据?
MySQL使用InnoDB引擎时一张表最大可以储存数据大小为 64TB,那为什么当表中的单行数据达到16KB时,这张表只能储存一条数据?
201 0
|
关系型数据库 MySQL 测试技术
只有.frm和.ibd文件时如何批量恢复InnoDB的表---发表到爱可生开源社区
很多时候因为MySQL数据库不能启动而造成数据无法访问,但应用的数据通常没有丢失,只是系统表空间等其它文件损坏了,或者遇到MySQL的bug。
155 0
|
存储 关系型数据库 MySQL
【MySQL从入门到精通】【高级篇】(七)设计一个索引&InnoDB中的索引方案
上一篇文章我们介绍了MySQL的存储引擎 【MySQL从入门到精通】【高级篇】(六)MySQL表的存储引擎,InnoDB与MyISAM的对比
128 0
【MySQL从入门到精通】【高级篇】(七)设计一个索引&InnoDB中的索引方案
|
存储 SQL 缓存
【MySQL从入门到精通】【高级篇】(六)MySQL表的存储引擎,InnoDB与MyISAM的对比
上一篇文章介绍了MySQL中SQL语句的执行流程 【MySQL从入门到精通】【高级篇】(五)MySQL的SQL语句执行流程,在介绍执行流程时提到了InnoDB和MyISAM两种存储引擎。这篇文章将来详细介绍下这两种存储引擎。
270 0
【MySQL从入门到精通】【高级篇】(六)MySQL表的存储引擎,InnoDB与MyISAM的对比
|
存储 关系型数据库 MySQL
MySQL InnoDB表和索引之聚簇索引与第二索引
MySQL InnoDB表和索引之聚簇索引与第二索引
99 0