MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(2)

性能和空间要求

使用以下算法之一处理ALTER TABLE操作:

● COPY:对原表的副本进行操作,将数据从原表中逐行复制到新表中。不允许并发DML。

● INPLACE:操作避免复制表数据,但可以就地重建表。在操作的准备和执行阶段,可能会简单地使用表上的独占元数据锁。通常,支持并发DML。

● INSTANT:操作只修改数据字典中的元数据。在准备和执行期间,不会对表执行排他元数据锁,并且表数据不受影响,从而使操作立即生效。允许并发DML。(MySQL8.0.12引入)

ALGORITHM子句是可选的。如果省略了ALGORITHM子句,MySQL将为存储引擎和ALTER TABLE子句使用支持的ALGORITHM=INSTANT,否则,将使用ALGORITHM=INPLACE。如果不支持ALGORITHM=INPLACE,则使用ALGORITHM=COPY。

指定ALGORITHM子句要求操作对支持它的子句和存储引擎使用指定的算法,否则将失败并返回错误。指定ALGORITHM=DEFAULT与省略ALGORITHM子句相同。

使用COPY算法的ALTER TABLE操作等待正在修改表的其他操作完成。对表副本应用更改后,将复制数据,删除原始表,并将表副本重命名为原始表的名称。执行ALTER TABLE操作时,其他会话可以读取原始表(很快会提到例外情况)。在 ALTER TABLE 操作开始后对表的更新和写入将被暂停,直到新表准备就绪,然后自动重定向到新表。表的临时副本是在原始表的数据库目录中创建的,除非使用 RENAME TO 操作将表移动到另一个不同路径的数据库。

前面提到的例外情况是ALTER TABLE 阻塞准备从表和表定义缓存中清除过时的表结构时读取(而不仅仅是写入)。此时,它必须获得独占锁。为此,它等待当前读完成,并阻止新的读写操作。

使用COPY算法的ALTER TABLE操作可防止并发DML操作。仍然允许并发查询。也就是说,表复制操作总是至少包含LOCK=SHARED的并发限制(允许查询,但是不允许DML)。通过指定LOCK=EXCLUSIVE,可以进一步限制支持LOCK子句的并发操作,这将阻止DML和查询。

要强制对ALTER TABLE操作使用COPY算法,否则将不使用它,请指定ALGORITHM=COPY或启用old_alter_table系统变量。如果old_alter_table设置与值不是DEFAULT的ALGORITHM子句之间存在冲突,则ALGORITHM子句优先。

对于InnoDB表,针对驻留在共享表空间中的表使用COPY算法的ALTER TABLE操作可以增加表空间的使用量。这样的操作需要与表中的数据加上索引一样多的额外空间。对于驻留在共享表空间中的表,操作期间使用的额外空间不会像独立表空间中的表那样释放回操作系统。

支持INPLACE算法的ALTER TABLE操作包括:

● InnoDB 联机DDL特性支持的ALTER TABLE操作。

● 重命名表。MySQL重命名与表tbl_name相对应的文件,而不进行复制。(也可以使用RENAME TABLE语句重命名表。)专门为重命名表授予的权限不会迁移到新名称。必须手动更改。

● 只修改表元数据的操作。这些操作是即时的,因为服务器不接触表内容。仅元数据操作包括:

■ 重命名列。在NDB Cluster 8.0.18及更高版本中,也可以联机执行此操作。

■ 更改列的默认值(NDB表除外)。

■ 通过在有效成员值列表的末尾添加新的枚举或集合成员来修改枚举或集合列的定义,只要数据类型的存储大小不变。例如,将一个成员添加到包含8个成员的SET列中,会将每个值所需的存储空间从1个字节更改为2个字节;这需要一个表副本。在列表中间添加成员会导致对现有成员重新编号,这需要表副本。

■ 更改空间列的定义来删除SRID属性。(添加或更改SRID属性需要重新生成,并且无法就地完成,因为服务器必须验证所有值是否都具有指定的SRID值。)

■ 从MySQL8.0.14开始,在满足以下条件时更改列字符集:

○ 列数据类型为CHAR、VARCHAR、TEXT或ENUM。

○ 字符集的更改是从utf8mb3更改为utf8mb4,或任何字符集更改为二进制。

○ 列上没有索引。

■ 从MySQL8.0.14开始,在满足以下条件时更改生成的列:

○ 对于InnoDB表,修改生成的存储列但不更改其类型、表达式或可为空的语句。

○ 对于非InnoDB表,是指修改生成的存储或虚拟列,但不更改其类型、表达式或可空的语句。

这种更改的一个例子是对列注释的更改。

● 重命名索引。

● 为InnoDB和NDB表添加或删除辅助索引。

● 对于NDB表,在可变宽度列上添加和删除索引的操作。这些操作是在线进行的,没有表复制,也没有在大多数持续时间内阻塞并发的DML操作。

● 使用ALTER INDEX操作修改索引可见性。

● 包含生成列的表的列修改,这些列依赖于具有默认值的列(如果已修改的列不包含在生成的列表达式中)。例如,可以在不重新生成表的情况下就地更改单独列的NULL属性。

支持INSTANT算法的ALTER TABLE操作包括:

● 添加列。此功能称为"即时添加列"。

● 添加或删除虚拟列。

● 添加或删除列默认值。

● 修改枚举或集合列的定义。对于ALGORITHM=INSTANT,上面描述的限制也同样适用。

● 更改索引类型。

● 重命名表。对于ALGORITHM=INSTANT,上面描述的限制也同样适用。

ALTER TABLE将MySQL 5.5临时列升级为5.6格式,用于ADD COLUMN、CHANGE COLUMN、MODIFY COLUMN、ADD INDEX和FORCE操作。不能使用INPLACE算法进行转换,因为表必须重建,在这种情况下指定ALGORITHM=INPLACE会引发错误,如有必要,指定ALGORITHM=COPY。

如果一个用于根据键对表进行分区的多列索引上的ALTER TABLE操作更改了列的顺序,则只能使用ALGORITHM=COPY执行。

WITHOUT VALIDATION和WITH VALIDATION子句影响ALTER TABLE是否对虚拟生成的列修改执行就地操作。

NDB Cluster 8.0支持使用与标准MySQL服务器相同的ALGORITHM=INPLACE语法进行联机操作。NDB不支持联机更改表空间;从NDB 8.0.21开始,不允许这样做。

ALTER TABLE 联合 DISCARD ... PARTITION ... TABLESPACE 或 IMPORT ... PARTITION ... TABLESPACE不创建任何临时表或临时分区文件。

ALTER TABLE 联合 ADD PARTITION、DROP PARTITION、COALESCE PARTITION、REBUILD PARTITION 或 REORGANIZE PARTITION 不会创建临时表(与NDB表一起使用时除外);但是,这些操作可以创建临时分区文件。

RANGE或LIST分区的ADD或DROP操作是立即操作或几乎是立即操作。除非使用LINEAR HASH 或 LINEAR KEY,否则HASH或KEY分区的ADD或者COALESCE操作会在所有分区之间复制数据;这实际上与创建新表相同,尽管ADD或COALESCE操作是按分区执行的。REORGANIZE操作只复制已更改的分区,不触及未更改的分区。

对于MyISAM表,可以通过将 myisam_sort_buffer_size 系统变量设置为较高的值来加快索引重新创建(转换过程中最慢的部分)。

并发控制

对于支持它的ALTER TABLE操作,可以使用LOCK子句来控制在表被修改时并发读和写的级别。为这个子句指定一个非默认值使您能够在修改操作期间要求一定数量的并发访问或排他性,并在请求的锁定程度不可用时停止操作。

使用ALGORITHM=INSTANT的操作只允许LOCK = DEFAULT。其他LOCK子句参数不适用。

LOCK子句的参数是:

MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(2)

给定ALGORITHM子句(如果有)和ALTER TABLE操作的最大并发级别:如果支持,则允许并发读和写。如果不支持,则允许并发读。如果不是,强制排他访问。

MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(2)

如果支持,允许并发读和写。否则,将出现错误。

MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(2)

如果支持,允许并发读,但阻塞写。即使存储引擎支持给定ALGORITHM子句(如果有的话)和ALTER TABLE操作的并发写操作,也会阻塞写操作。如果不支持并发读取,则会发生错误。

MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(2)

执行独占访问。即使存储引擎对给定的ALGORITHM子句(如果有的话)和ALTER TABLE操作支持并发读/写,也会执行此操作。

官方文档地址:
https://dev.mysql.com/doc/refman/8.0/en/alter-table.html

MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句(2)

上一篇:RedisDBM技术介绍


下一篇:MySQL的SQL语句 - 数据定义语句(6)- ALTER TABLE 语句 (4)