MySQL 8.0 新特性:Instant Add Column

文若2年前技术文章1925


一、前言

MySQL 8.0 支持 “快速加列” 功能,既添加字段时可以支持 “INSTANT” 快速完成。通过只修改数据字典的方法来实现大表快速加列,避免之前加列操作必须做的数据拷贝,从而大幅缩小大表加列所需的时间,减少对系统的影响。

支持版本:

MySQL 版本  8.0.12 及以上

腾讯云内核版本 MySQL 5.7 20190830 及以上

腾讯云内核版本 MySQL 8.0 20200630 及以上

二、测试

1. 准备数据
root@mysql 14:12:  [sbtest]>select count(*) from sbtest2;
+----------+
| count(*) |
+----------+
|   200000 |
+----------+
1 row in set (0.04 sec)
2. 添加字段

使用 INSTANT 算法给 20 万行数据表添加字段:

root@mysql 14:17:  [sbtest]>ALTER TABLE sbtest2 ADD COLUMN d  varchar(10) DEFAULT 'abc',ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.10 sec)
Records: 0  Duplicates: 0  Warnings: 0

使用 INPLACE 算法给 20 万行数据表添加字段:

root@mysql 14:19:  [sbtest]>ALTER TABLE sbtest2 ADD COLUMN e varchar(10) DEFAULT 'abc',ALGORITHM=INPLACE;
Query OK, 0 rows affected (6.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

对比看 快速加列 的优化效果很明显,几乎是毫秒级就可以完成。

2. 验证
root@mysql 14:18:  [sbtest]>select id,d  from sbtest2 limit 10;
+----+------+
| id | d    |
+----+------+
|  1 | abc  |
|  2 | abc  |
|  3 | abc  |
|  4 | abc  |
|  5 | abc  |
|  6 | abc  |
|  7 | abc  |
|  8 | abc  |
|  9 | abc  |
| 10 | abc  |
+----+------+
10 rows in set (0.00 sec)

三、工作原理

1. 快速加列

在没有 快速加列的功能时,每次添加字段都需要重建表空间,就需要大量的 IO 及时间。

当使用 快速加列时,只会修改数据字典,增加 新列的定义新列的默认值。需要读取数据时 MySQL 会将 新增列的默认值,追加到读取的数据后。

需要写入数据时,使用了新的数据格式 (增加了 instant 标志位 和 "列数" 字段)。

相当于是 伪造列,那么是否可以一直伪造下去呢?

2. 限制
  1. 添加列的操作不能与其它 ALTER TABLE 操作放在同一条语句组合中。

  2. 在 MySQL 8.0.29 之前,一列只能作为表的最后一列添加,不支持将列添加到其他列中的任何其他位置。从 MySQL 8.0.29 开始,可以将即时添加的列添加到表中的任何位置。

  3. ROW_FORMAT=COMPRESSED、具有 FULLTEXT 的表、临时表不支持 Instant Add Column。

  4. 添加列会评估行的大小,如果超出限制会抛出异常:ERROR 4092 (HY000): Column can't be added with ALGORITHM=INSTANT as after this max possible row size crosses max permissible row size. Try ALGORITHM=INPLACE/COPY.

3. 表维护

现在回答刚才的问题,是否可以一直伪造下去?

当使用 Instant 添加一个列或多个列时,都会创建一个新的行版本,当超出限制时会抛出异常。

可以通过查询 INFORMATION_SCHEMA.INNODB_TABLES来查询行版本:

-- Version: 8.0.29
SELECT NAME, TOTAL_ROW_VERSIONS FROM INFORMATION_SCHEMA.INNODB_TABLES;

TOTAL_ROW_VERSIONS 大于 64 会报错:ERROR 4080 (HY000): Maximum row versions reached for table test/t1. No more columns can be added or dropped instantly. Please use COPY/INPLACE.使用 ALTER TABLE 重建表空间时 TOTAL_ROW_VERSIONS 会归 0。

相关文章

linux下ext4类型文件系统/目录扩容

1、查看分区信息[root@172-16-121-112 ~]# fdisk -lDisk /dev/vda: 107.4 GB, 107374182400 bytes, 209715200 sect...

Prometheus集成pushgateway监控k8s集群

Prometheus集成pushgateway监控k8s集群

Prometheus部署环境介绍本文的k8s环境是通过二进制方式搭建的v1.20.13版本清单准备注意集群版本的坑,自己先到Github上下载对应的版本。注意: 集群版本在v1.21.x之前需要注意下...

寻找CPU使用率高进程方法

寻找CPU使用率高进程方法

背景节点报CPU使用率高,需要定位是什么进程占用CPU使用率高。CPU使用率持续较高在对应节点使用 “top”命令,然后键盘输入“P”,即按照CPU使用率排序进程。执行ps -ef | grep &l...

将Nexus作为容器镜像仓库的配置过程

将Nexus作为容器镜像仓库的配置过程

Docker,Helm和Kubernetes的简化容器管理Nexus Repository建立在广泛的企业存储功能之上,是适用于所有Docker镜像和Helm Chart存储库的强大的注册表。Nexu...

InnoDB秘籍:MVCC机制与行锁的深度探索

InnoDB秘籍:MVCC机制与行锁的深度探索

前言事务的起源可以追溯到 6000 年以前,当时苏美尔人(Sumerians)就发明了事务处理和记录的方法。已知最早的记录是写在土块上的,上面写了皇家的税收、土地、谷物、牲畜、奴隶和黄金,明确地记下了...

docker网络介绍

docker网络介绍

一、docker网络介绍安装docker时,会自动创建三个网络。可以使用docker network ls命令列出这些网络Docker内置这三个网络,运行容器时,可以使用--network标志来指定容...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。