首页 > 数据库 >MySQL 8.0 instant 添加和删除列

MySQL 8.0 instant 添加和删除列

时间:2024-02-20 22:23:48浏览次数:32  
标签:8.0 abc instant name +-----------+--------------------+ MySQL table row myabc

MySQL 8.0.12 开始, 以下的 alter table 操作支持 ALGORITHM=INSTANT 算法:

1.添加新的列。即 instant add column

2.添加或者删除虚拟列

3.添加或者删除列的默认值

4.修改 enum、set 类型列的定义

5.修改索引类型

6.重命名表

 

支持 ALGORITHM=INSTANT 算法的操作,只会修改数据字典的元数据。不需要在表上施加元数据锁,也不影响表的数据,从而使得操作可以瞬间完成。

即使没有显式的加上 ALGORITHM=INSTANT 选项,只要操作支持 instant 操作,就会默认使用该特性;如果是不支持的操作,显式加上 ALGORITHM=INSTANT 选项会失败并报错。

 

MySQL 8.0.28 开始, InnoDB 支持 ALTER TABLE ... RENAME COLUMN 操作使用 ALGORITHM=INSTANT。

MySQL 8.0.29 开始, InnoDB 支持 ALTER TABLE ... DROP COLUMN 操作使用 ALGORITHM=INSTANT。在 8.0.29 之前, instant 添加列,只能是加在表的最后,从8.0.29开始,可以在表的任意位置添加。

ALGORITHM=INSTANT 是如何工作的

表元数据中引入了行版本这一新概念。该特性的工作原理是,在插入一条记录时,会给该记录打上"行版本"的印记,也就是在表元数据中当前的行版本。如果表没有经过任何 alter table ... add/drop column, 表中所有行的行版本号就是0。在记录的头部,有4个位(bit)用于元数据,即 info-bits,其中有一个 bit 是没有使用的。因此该 bit 被用来表示记录是否有行版本。缺省情况下,该 bit 是没有被置位的。如果该 bit 被置位了,则会在记录头部存储记录版本号。这样,就容易实现在不重构表的情况下,执行 "alter table ... add/drop column",此外使用已经存在的一个 bit,instant add/drop ddl 在升级表的时候也可以正常工作。

 

每个 "alter table ... add/drop column" 语句,都会创建一个行版本。在 alter table 语句执行后插入的记录会使用新的行版本号标记。因此,执行过多次 alter table 操作的表,可能存在多个不同的行版本。一旦记录被读取,就会转换成表元数据的最新的行版本号。当前的行版本是表的元数据信息,而记录的行版本是行元数据。

 

行版本只是绑定了 alter table 操作,而不是绑定了每个被添加、删除的列。比如,一个"alter table ... add/drop column" 添加了n个列,删除了m个列,当时行版本只是增加一。

版本限制

instant 添加或删除列,行版本号元数据最多支持64个版本。可以通过information_schema.innodb_tables.total_row_versions 列来查看。如果"alter table ... add/drop column"超过64次,就会切换成老的方式,进行表的重构。所以,超过 64 次之后还显式指定 algorithm=instant ,会报如下错误:

ERROR 4080 (HY000): Maximum row versions reached for table test/t1. No more columns can be added or dropped instantly. Please use COPY/INPLACE.

行版本演示

root@localhost abc>create table myabc(id int);

Query OK, 0 rows affected (0.01 sec)

root@localhost abc>select name,total_row_versions from information_schema.innodb_tables where name like '%myabc';
+-----------+--------------------+
| name      | total_row_versions |
+-----------+--------------------+
| abc/myabc |                  0 |
+-----------+--------------------+
1 row in set (0.03 sec)

root@localhost abc>alter table myabc add column name char(10) first, algorithm=instant;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

root@localhost abc>select name,total_row_versions from information_schema.innodb_tables where name like '%myabc';
+-----------+--------------------+
| name      | total_row_versions |
+-----------+--------------------+
| abc/myabc |                  1 |
+-----------+--------------------+
1 row in set (0.02 sec)

root@localhost abc>alter table myabc drop column name, algorithm=instant;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

root@localhost abc>select name,total_row_versions from information_schema.innodb_tables where name like '%myabc';
+-----------+--------------------+
| name      | total_row_versions |
+-----------+--------------------+
| abc/myabc |                  2 |
+-----------+--------------------+
1 row in set (0.00 sec)

root@localhost abc>

表重建和 truncate 表

其它类型的 alter table 操作,比如 optimizer table 会重建表。一旦表被重建,instant 元数据就会被清除。

root@localhost abc>select name,total_row_versions from information_schema.innodb_tables where name like '%myabc';
+-----------+--------------------+
| name      | total_row_versions |
+-----------+--------------------+
| abc/myabc |                  2 |
+-----------+--------------------+
1 row in set (0.00 sec)

root@localhost abc>optimize table myabc;
+-----------+----------+----------+-------------------------------------------------------------------+
| Table     | Op       | Msg_type | Msg_text                                                          |
+-----------+----------+----------+-------------------------------------------------------------------+
| abc.myabc | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| abc.myabc | optimize | status   | OK                                                                |
+-----------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.03 sec)

root@localhost abc>select name,total_row_versions from information_schema.innodb_tables where name like '%myabc';
+-----------+--------------------+
| name      | total_row_versions |
+-----------+--------------------+
| abc/myabc |                  0 |
+-----------+--------------------+
1 row in set (0.02 sec)

root@localhost abc>

truncate 表也是如此。

 

是否真是瞬间完成

可以通过时间对比,来确认是否真是瞬间完成。

root@localhost abc> select count(*) from myabc;
+----------+
| count(*) |
+----------+
|  9000000 |
+----------+
1 row in set (0.32 sec)
 
root@localhost abc> alter table myabc add column name char(10), algorithm=copy;
Query OK, 9000000 rows affected (39.01 sec)
Records: 9000000  Duplicates: 0  Warnings: 0
 
root@localhost abc> alter table myabc add column name2 char(10), algorithm=instant;
Query OK, 0 rows affected (0.10 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

标签:8.0,abc,instant,name,+-----------+--------------------+,MySQL,table,row,myabc
From: https://www.cnblogs.com/abclife/p/18020968

相关文章

  • linux下部署MySQL服务
    linux下部署MySQL服务1、安装sudo-s调整为root下用户角色运行以下命令安装MySQL,输入Y继续sudoaptinstallmysql-server2、启动systemctlstartmysqld设置MySQL开机自启动(可选)systemctlenablemysqld3、检查运行状态systemctlstatusmysqld4、配置MySQL用户......
  • MySQL
    库的增删改查(1)语法#增createdatabasedb1;createdatabasedb2charset='gbk'#查showdatabases;#查所有的库showcreatedatabasedb1;#查单个#改alterdatabasedb2charset='utf-8'#删dropdatabasedb2;表的增删改查(1)语法#查看当前所在的库的名字......
  • 在 Linux 系统上安装 mysql 5.7
    准备工作下载MySQL:下载页面、下载地址创建MySQL用户组、用户、相关目录、日志文件#创建新用户组groupaddmysql#创建用户mysql,指定所属用户组为mysql,禁止其登录useradd-r-gmysql-s/sbin/nologin#创建安装目录(可以自定义,这里以“/usr/local/mysql”为例)mk......
  • MySQL——数据处理函数
    MySQL——数据处理函数数据处理函数又被称为单行处理函数,单行处理函数的特点:一个输入对应一个输出.语法格式:select单行处理函数(字段名)from表名;常见单行处理函数转换小写:lower()转换大写:upper()取子串:substr(),语法为substr(字段名,头,尾)。注意:起始下标是从1开......
  • mysql锁表
    要查看MySQL数据库中的锁信息,可以使用以下方法之一:使用 SHOWFULLPROCESSLIST:这个命令将显示当前MySQL实例中正在执行的所有进程,包括它们所持有的锁信息。在终端中执行以下命令:sql复制代码SHOWFULLPROCESSLIST;这将列出当前连接到MySQL实例的所有客户端会话,并......
  • mysql: show processlist 详解
    showprocesslist显示的信息都是来自MySQL系统库information_schema中的processlist表。所以使用下面的查询语句可以获得相同的结果:select*frominformation_schema.processlist了解这些基本信息后,下面我们看看查询出来的结果都是什么意思。Id:就是这个线程的唯一标......
  • ESXi 8.0 下查看硬盘状态
    从PERC系列8和更新的系列起,PERCCLI已取代MegaCli下载VMwarePERCCLI实用程序:https://www.dell.com/support/home/zh-cn/drivers/driversdetails?driverid=xmm4v&oscode=xi80&productcode=poweredge-r740PERCCLI_7.2616.0000_VMWARE.tar.gz下载后解压对应的vip文件使用以下......
  • 使用pymysql模块操作MySQL
    第一步:安装pipinstallpymysql第二步:使用方式#导入模块importpymysql#建立连接conn=pymysql.connect(user='root',password="root",host='127.0.0.1',database='cars')#创建游标,查询数据默认为元组类型cursor=conn.cursor......
  • ESXi 8.0 下改Delll idrac密码
    ESXi8.0 下下载:https://www.dell.com/support/home/zh-cn/product-support/product/poweredge-r740/drivershttps://dl.dell.com/FOLDER09667707M/1/Dell-iDRACTools-Web-ESXi.VIB-11.1.0.0-5294_A00.zip?uid=80aaf26c-07a6-4c60-3f53-df177f2da03f&fn=Dell-iDRACTools-We......
  • 在 CentOS7 部署 ELK8.0
    1、环境准备:关闭防火墙与selinuxsetenforce0#临时关闭SELinuxsed-i 's/SELINUX=enforcing/SELINUX=disabled/g'/etc/selinux/config #永久关闭SELnux(重启生效)2、修改Linux最大打开文件数cat/etc/security/limits.conf|grep-v"^#"|grep-v"^$"*......