原文地址:https://Mysqlserverteam.com/mysql-8-0-innodb-now-supports-instant-add-column/ 长期以来,即时DDL一直是最受欢迎的InnoDB功能之一。对
原文地址:https://Mysqlserverteam.com/mysql-8-0-innodb-now-supports-instant-add-column/
长期以来,即时DDL一直是最受欢迎的InnoDB功能之一。对于越来越大且快速增长的数据集,任何网络规模数据库中必须具备立即执行DDL的功能。 开发人员经常需要添加新列,以满足不断变化的业务需求。即时加字段(add column)的功能是我们一系列instantly DDL语句中的第一个。 在Mysql 8.0中迁移到新的事务数据字典使我们的这项工作变得容易得多。在MySQL 8.0之前,元数据(数据字典)存储在称为.frm文件的平面文件中, .frm文件是一种不可思议的格式,已近过时很久了。 该即时加列补丁是由腾讯游戏数据库管理员团队提供的,我们要感谢并感谢腾讯游戏所做的重要而及时的贡献。MySQL 5.6是第一个支持INPLACE DDL的版本。在MySQL 5.6之前,执行DDL的唯一方法是逐行复制行。
INPLACE DDL主要由InnoDB处理,而逐行COPY在服务器层处理。直到8.0(请参阅实验版本),InnoDB甚至通过为INPLACE DDL算法重建表来向表中添加列。
许多用户向我们询问了如何避免耗时的schema changes。现在,可以通过(始终)指定ALGoRITHM = INSTANT来实现,这将保证操作立即完成(如果不支持则无法完成)。
此外,如果根本未指定ALGORITHM,则服务器将首先尝试DEFAULT = INSTANT算法,如果无法完成,则服务器将尝试INPLACE算法;如果SE无法支持,服务器将最终尝试COPY算法。
新语法如下:
ALTER TABLE table_name [alter_specification], ALGORITHM=INSTANT;
INSTANT算法的优势在于,仅在数据字典中进行元数据更改。 SE更改期间无需获取元数据锁定,也不会touch表中的数据。ALTER TABLE t1 ALTER COLUMN i SET DEFAULT 11, ALGORITHM=INSTANT, LOCK=NONE;
ERROR HY000: Incorrect usage of ALGORITHM=INSTANT and LOCK=NONE/SHARED/EXCLUSIVE
# ALGORITHM=INSTANT and LOCK=DEFAULT are OK though.
ALTER TABLE t1 ALTER COLUMN i SET DEFAULT 13, ALGORITHM=INSTANT, LOCK=DEFAULT;
如果将ALGORITHM = INSTANT设置为无法不支持的DDL,则会出现错误,如下所示。这里的想法是不支持的情况下会直接失败,而不会默认转换并切换到幕后的另一种算法。ALTER TABLE t1 ALTER COLUMN i SET DEFAULT 12, DROP COLUMN j, ALGORITHM=INSTANT;
ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE
当前,Innodb的即时DDL支持如下操作
mysql> CREATE TABLE t1 (a INT, b INT, KEY(b));
Query OK, 0 rows affected (0.70 sec)
mysql> # Modify the index can be instant if it"s a trivial change
mysql> ALTER TABLE t1 DROP KEY b, ADD KEY b(b) USING BTREE, ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.14 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> # Rename the table through ALTER TABLE can be instant
mysql> ALTER TABLE t1 RENAME TO t2, ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.26 sec)
mysql> # SET DEFAULT to a column can be instant
mysql> ALTER TABLE t2 ALTER COLUMN b SET DEFAULT 100, ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> # DROP DEFAULT to a column can be instant
mysql> ALTER TABLE t2 ALTER COLUMN b DROP DEFAULT, ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> # MODIFY COLUMN can be instant
mysql> ALTER TABLE t2 ADD COLUMN c ENUM("a", "b", "c"), ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.35 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE t2 MODIFY COLUMN c ENUM("a", "b", "c", "d", "e"), ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> # ADD/DROP virtual column can be instant
mysql> ALTER TABLE t2 ADD COLUMN (d INT GENERATED ALWAYS AS (a + 1) VIRTUAL), ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.38 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE t2 DROP COLUMN d, ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.40 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> # Do two operations instantly in the same statement
mysql> ALTER TABLE t2 ALTER COLUMN a SET DEFAULT 20, ALTER COLUMN b SET DEFAULT 200, ALGORITHM = INSTANT;
Query OK, 0 rows affected (0.20 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DROP TABLE t2;
Query OK, 0 rows affected (0.36 sec)
2,“即时”加字段的过程:基于行的存储规则发生变化之后(增加字段),仅修改元数据
,
3,“即时”加字段之后,查询的处理过程。
4,“即时”加字段后,新增数据的处理
如何观察(Instant column) 用户可以通过infORMation_schema中的视图观察即时添加列的结果。更具体地说,一些新字段将添加到information_schema.innodb_tables和information_schema.innodb_columns。 请注意,对于可以立即完成的其他操作,无需提供新的观察状态。请参见下面的示例:
mysql> CREATE TABLE t1 (a INT, b INT);
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT table_id, name, instant_cols FROM information_schema.innodb_tables WHERE name LIKE "%t1%";
+----------+---------+--------------+
| table_id | name | instant_cols |
+----------+---------+--------------+
| 1065 | test/t1 | 0 |
+----------+---------+--------------+
1 row in set (0.22 sec)
mysql> SELECT table_id, name, has_default, default_value FROM information_schema.innodb_columns WHERE table_id = 1065;
+----------+------+-------------+---------------+
| table_id | name | has_default | default_value |
+----------+------+-------------+---------------+
| 1065 | a | 0 | NULL |
| 1065 | b | 0 | NULL |
+----------+------+-------------+---------------+
2 rows in set (0.38 sec)
可以看到,在innodb_tables中引入了一个新的名为“ instant_cols”的列,该列代表即时列的数量,
而在innodb_columns中引入了两个有关默认值的新列,分别名为“ has_default”和“ default_value”。
mysql> ALTER TABLE t1 ADD COLUMN c INT, ADD COLUMN d INT DEFAULT 1000, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SELECT table_id, name, instant_cols FROM information_schema.innodb_tables WHERE name LIKE "%t1%";
+----------+---------+--------------+
| table_id | name | instant_cols |
+----------+---------+--------------+
| 1065 | test/t1 | 2 |
+----------+---------+--------------+
1 row in set (0.03 sec)
mysql> SELECT table_id, name, has_default, default_value FROM information_schema.innodb_columns WHERE table_id = 1065;
+----------+------+-------------+---------------+
| table_id | name | has_default | default_value |
+----------+------+-------------+---------------+
| 1065 | a | 0 | NULL |
| 1065 | b | 0 | NULL |
| 1065 | c | 1 | NULL |
| 1065 | d | 1 | 800003e8 |
+----------+------+-------------+---------------+
4 rows in set (0.36 sec)
请注意,table_id不变。这不再是table的重建!正如我们所看到的,"instant_cols"现在设置为2,这意味着在第一个即时ADD COLUMN发生时表中有a列和b列。
在innodb_columns中记住c和d列的默认值。现在,如果has_default为1,则用户可以知道是否立即添加了列。
此外,如果“ has_default”为1,则此列的默认值存储在“ default_value”字段中。d的default_value设置为值1000的内部二进制格式。
mysql> ALTER TABLE t1 ADD COLUMN e VARCHAR(100) DEFAULT "Hello MySQL!";
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SELECT table_id, name, instant_cols FROM information_schema.innodb_tables WHERE name LIKE "%t1%";
+----------+---------+--------------+
| table_id | name | instant_cols |
+----------+---------+--------------+
| 1065 | test/t1 | 2 |
+----------+---------+--------------+
1 row in set (0.03 sec)
mysql> SELECT table_id, name, has_default, default_value FROM information_schema.innodb_columns WHERE table_id = 1065;
+----------+------+-------------+--------------------------+
| table_id | name | has_default | default_value |
+----------+------+-------------+--------------------------+
| 1065 | a | 0 | NULL |
| 1065 | b | 0 | NULL |
| 1065 | c | 1 | NULL |
| 1065 | d | 1 | 800003e8 |
| 1065 | e | 1 | 48656c6c6f204d7953514c21 |
+----------+------+-------------+--------------------------+
5 rows in set (0.36 sec)
又过一会儿再添加一列,table_id依旧次保持不变。 “ instant_cols”将保持不变,并且还会记住e列的默认值。
--结束END--
本文标题: MySQL 8.0 InnoDB对即时加字段的支持(instant add column)(译)
本文链接: https://www.lsjlt.com/news/6047.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0