在线 DDL 改善了 MySQL 操作的多个方面:Online DDL improves several aspects of MySQL operation:
访问该表的应用程序响应速度更快,因为在 DDL 操作进行的同时,对该表的查询和 DML 操作仍然可以执行。减少对 MySQL 服务器资源的锁定和等待,即使是与 DDL 操作无关的操作,也能实现更好的可扩展性。Applications that access the table are more responsive because queries and DML operations on the table can proceed while the DDL operation is in progress. Reduced locking and waiting for MySQL server resources leads to greater scalability, even for operations that are not involved in the DDL operation.
即时操作仅修改数据字典中的元数据。在操作执行阶段,表可能会暂时获得一个独占的元数据锁。表数据不受影响,使操作瞬时完成。允许并发的 DML 操作。Instant operations only modify metadata in the data dictionary. An exclusive metadata lock on the table may be taken briefly during the execution phase of the operation. Table data is unaffected, making operations instantaneous. Concurrent DML is permitted.
在线操作避免了与表复制方法相关的磁盘 I/O 和 CPU 周期,从而最小化数据库的整体负载。最小化负载有助于在 DDL 操作期间保持良好的性能和高吞吐量。Online operations avoid the disk I/O and CPU cycles associated with the table-copy method, which minimizes overall load on the database. Minimizing load helps maintain good performance and high throughput during the DDL operation.
在线操作比表复制操作将更少的数据读入缓冲池,这减少了从内存中清除经常访问的数据的情况。清除经常访问的数据可能会在 DDL 操作后导致暂时的性能下降。Online operations read less data into the buffer pool than table-copy operations, which reduces purging of frequently accessed data from memory. Purging of frequently accessed data can cause a temporary performance dip after a DDL operation.
默认情况下,MySQL 在执行 DDL 操作时会尽量减少锁定。如果需要,可以在就地操作和某些复制操作中指定 LOCK 子句以强制更严格的锁定。如果 LOCK 子句指定的锁定级别低于特定 DDL 操作允许的级别,则语句会报错。LOCK 子句按从最不严格到最严格的顺序描述如下:By default, MySQL uses as little locking as possible during a
DDL operation. The LOCK clause can be
specified for in-place operations and some copy operations to
enforce more restrictive locking, if required. If the
LOCK clause specifies a less restrictive
level of locking than is permitted for a particular DDL
operation, the statement fails with an error.
LOCK clauses are described below, in order of
least to most restrictive:
LOCK=NONE:允许并发查询和 DML 操作。Permits concurrent queries and DML.
例如,对于涉及客户注册或购买的表,可以使用此子句,以避免在长时间的 DDL 操作期间使表不可用。For example, use this clause for tables involving customer signups or purchases, to avoid making the tables unavailable during lengthy DDL operations.
LOCK=SHARED:允许并发查询,但阻止 DML 操作。Permits concurrent queries but blocks DML.
例如,在数据仓库表上使用此子句,你可以将数据加载操作延迟到 DDL 操作完成之后,但查询不能长时间延迟。For example, use this clause on data warehouse tables, where you can delay data load operations until the DDL operation is finished, but queries cannot be delayed for long periods.
LOCK=DEFAULT:允许尽可能多的并发(并发查询、DML,或两者)。省略
LOCK子句等同于指定LOCK=DEFAULT。Permits as much concurrency as possible (concurrent queries, DML, or both). Omitting theLOCKclause is the same as specifyingLOCK=DEFAULT.当你预计 DDL 语句的默认锁定级别不会对表的可用性造成任何问题时,请使用此子句。Use this clause when you do not expect the default locking level of the DDL statement to cause any availability problems for the table.
LOCK=EXCLUSIVE:阻止并发查询和 DML 操作。Blocks concurrent queries and DML.
如果主要关注的是以最短的时间完成 DDL 操作,并且不需要并发的查询和 DML 访问,请使用此子句。如果服务器预计处于空闲状态以避免意外的表访问,也可以使用此子句。Use this clause if the primary concern is finishing the DDL operation in the shortest amount of time possible, and concurrent query and DML access is not necessary. You might also use this clause if the server is supposed to be idle, to avoid unexpected table accesses.
在线 DDL 操作可以被视为有三个阶段:Online DDL operations can be viewed as having three phases:
阶段 1:初始化Phase 1: Initialization
在初始化阶段,服务器会确定在操作期间允许的并发量,同时考虑存储引擎功能、语句中指定的操作以及用户指定的
ALGORITHM和LOCK选项。在此阶段,会获取一个可升级的共享元数据锁以保护当前的表定义。In the initialization phase, the server determines how much concurrency is permitted during the operation, taking into account storage engine capabilities, operations specified in the statement, and user-specifiedALGORITHMandLOCKoptions. During this phase, a shared upgradeable metadata lock is taken to protect the current table definition.阶段 2:执行Phase 2: Execution
在此阶段,语句被准备并执行。元数据锁是否升级为排他锁取决于初始化阶段评估的因素。如果需要排他元数据锁,则仅在语句准备期间短暂获取。In this phase, the statement is prepared and executed. Whether the metadata lock is upgraded to exclusive depends on the factors assessed in the initialization phase. If an exclusive metadata lock is required, it is only taken briefly during statement preparation.
阶段 3:提交表定义Phase 3: Commit Table Definition
在提交表定义阶段,元数据锁会升级为排他锁,以驱逐旧的表定义并提交新的表定义。一旦授予,排他元数据锁的持续时间很短。In the commit table definition phase, the metadata lock is upgraded to exclusive to evict the old table definition and commit the new one. Once granted, the duration of the exclusive metadata lock is brief.
由于上述专用元数据锁要求,在线 DDL 操作可能需要等待持有表元数据锁的并发事务提交或回滚。在 DDL 操作开始之前或期间启动的事务可能会持有正在被更改的表的元数据锁。在长时间运行或不活动的事务情况下,在线 DDL 操作可能会因为等待专用元数据锁而超时。此外,在线 DDL 操作请求的待处理专用元数据锁会阻塞该表上的后续事务。Due to the exclusive metadata lock requirements outlined above, an online DDL operation may have to wait for concurrent transactions that hold metadata locks on the table to commit or rollback. Transactions started before or during the DDL operation can hold metadata locks on the table being altered. In the case of a long running or inactive transaction, an online DDL operation can time out waiting for an exclusive metadata lock. Additionally, a pending exclusive metadata lock requested by an online DDL operation blocks subsequent transactions on the table.
下面的示例演示了在线 DDL 操作等待专用元数据锁,以及待处理元数据锁如何阻塞该表上的后续事务。The following example demonstrates an online DDL operation waiting for an exclusive metadata lock, and how a pending metadata lock blocks subsequent transactions on the table.
会话 1:Session 1:
mysql> CREATE TABLE t1 (c1 INT) ENGINE=InnoDB; mysql> START TRANSACTION; mysql> SELECT * FROM t1;
会话 1 的 SELECT 语句对表 t1 获取了共享元数据锁。The session 1 SELECT statement
takes a shared metadata lock on table t1.
会话 2:Session 2:
mysql> ALTER TABLE t1 ADD COLUMN x INT, ALGORITHM=INPLACE, LOCK=NONE;
会话 2 中的在线 DDL 操作,需要对表 t1 获取排他元数据锁以提交表定义更改,必须等待会话 1 的事务提交或回滚。The online DDL operation in session 2, which requires an exclusive metadata lock on table t1 to commit table definition changes, must wait for the session 1 transaction to commit or roll back.
会话 3:Session 3:
mysql> SELECT * FROM t1;
会话 3 中发出的 SELECT 语句被阻塞,等待会话 2 中 ALTER TABLE 操作请求的排他元数据锁被授予。The SELECT statement issued in
session 3 is blocked waiting for the exclusive metadata lock
requested by the ALTER TABLE
operation in session 2 to be granted.
您可以使用 SHOW FULL
PROCESSLIST 来确定事务是否在等待元数据锁。You can use
SHOW FULL
PROCESSLIST to determine if transactions are waiting
for a metadata lock.
mysql> SHOW FULL PROCESSLIST\G
...
*************************** 2. row ***************************
Id: 5
User: root
Host: localhost
db: test
Command: Query
Time: 44
State: Waiting for table metadata lock
Info: ALTER TABLE t1 ADD COLUMN x INT, ALGORITHM=INPLACE, LOCK=NONE
...
*************************** 4. row ***************************
Id: 7
User: root
Host: localhost
db: test
Command: Query
Time: 5
State: Waiting for table metadata lock
Info: SELECT * FROM t1
4 rows in set (0.00 sec)
元数据锁信息也可以通过性能模式 metadata_locks 表暴露出来,该表提供有关会话之间元数据锁依赖关系、会话正在等待的元数据锁以及当前持有元数据锁的会话的信息。更多信息,请参见 第 29.12.13.3 节,“The metadata_locks 表”。Metadata lock information is also exposed through the
Performance Schema metadata_locks
table, which provides information about metadata lock
dependencies between sessions, the metadata lock a session is
waiting for, and the session that currently holds the metadata
lock. For more information, see
Section 29.12.13.3, “The metadata_locks Table”.
DDL 操作的性能在很大程度上取决于操作是否即时执行、是否就地执行以及是否重建表。The performance of a DDL operation is largely determined by whether the operation is performed instantly, in place, and whether it rebuilds the table.
要评估 DDL 操作的相对性能,您可以比较使用 ALGORITHM=INSTANT、ALGORITHM=INPLACE 和 ALGORITHM=COPY 的结果。也可以在启用 old_alter_table 的情况下运行语句,以强制使用 ALGORITHM=COPY。To assess the relative performance of a DDL operation, you can
compare results using ALGORITHM=INSTANT,
ALGORITHM=INPLACE, and
ALGORITHM=COPY. A statement can also be run
with old_alter_table enabled to
force the use of ALGORITHM=COPY.
对于修改表数据的 DDL 操作,您可以通过查看命令完成后显示的 “受影响的行” 值来确定 DDL 操作是就地进行更改还是执行表复制。例如:For DDL operations that modify table data, you can determine whether a DDL operation performs changes in place or performs a table copy by looking at the “rows affected” value displayed after the command finishes. For example:
更改列的默认值(快速,不影响表数据):Changing the default value of a column (fast, does not affect the table data):
Query OK, 0 rows affected (0.07 sec)
添加索引(需要时间,但
0 rows affected表明表未被复制):Adding an index (takes time, but0 rows affectedshows that the table is not copied):Query OK, 0 rows affected (21.42 sec)
更改列的数据类型(需要大量时间并且需要重建表中的所有行):Changing the data type of a column (takes substantial time and requires rebuilding all the rows of the table):
Query OK, 1671168 rows affected (1 min 35.54 sec)
在对大表运行 DDL 操作之前,请按照以下步骤检查操作是快还是慢:Before running a DDL operation on a large table, check whether the operation is fast or slow as follows:
克隆表结构。Clone the table structure.
向克隆的表中填充少量数据。Populate the cloned table with a small amount of data.
在克隆的表上运行 DDL 操作。Run the DDL operation on the cloned table.
检查“受影响的行数”值是否为零。非零值表示操作会复制表数据,这可能需要特别的计划。例如,您可能会在计划的停机时间内执行 DDL 操作,或者在每个副本服务器上逐一执行。Check whether the “rows affected” value is zero or not. A nonzero value means the operation copies table data, which might require special planning. For example, you might do the DDL operation during a period of scheduled downtime, or on each replica server one at a time.
为了更好地理解与 DDL 操作相关的 MySQL 处理,可以在 DDL 操作前后检查 Performance Schema 和 INFORMATION_SCHEMA 中与 InnoDB 相关的表,以查看物理读取、写入、内存分配等数量。For a greater understanding of the MySQL processing associated
with a DDL operation, examine Performance Schema and
INFORMATION_SCHEMA tables related to
InnoDB before and after DDL operations to
see the number of physical reads, writes, memory allocations,
and so on.
Performance Schema 阶段事件可以用来监控 ALTER TABLE 的进程。请参见 第 17.16.1 节,“使用 Performance Schema 监控 InnoDB 表的 ALTER TABLE 进度”。Performance Schema stage events can be used to monitor
ALTER TABLE progress. See
Section 17.16.1, “Monitoring ALTER TABLE Progress for InnoDB Tables Using Performance
Schema”.
由于涉及记录并发 DML 操作所做更改的某些处理工作,然后在最后应用这些更改,因此在线 DDL 操作的整体耗时可能比阻止其他会话访问表的表复制机制更长。原始性能的下降与使用该表的应用程序的更好响应性相平衡。在评估更改表结构的技术时,应考虑最终用户对性能的感知,这基于诸如网页加载时间等因素。Because there is some processing work involved with recording the changes made by concurrent DML operations, then applying those changes at the end, an online DDL operation could take longer overall than the table-copy mechanism that blocks table access from other sessions. The reduction in raw performance is balanced against better responsiveness for applications that use the table. When evaluating the techniques for changing table structure, consider end-user perception of performance, based on factors such as load times for web pages.