MySQL 8.0-13.1.1 Atomic Data Definition Statement Support(支持原子数据定义语句)

MySQL 8.0 supports atomic Data Definition Language (DDL) statements. This feature is referred to as atomic DDL. An atomic DDL statement combines the data dictionary updates, storage engine operations, and binary log writes associated with a DDL operation into a single, atomic operation. The operation is either committed, with applicable changes persisted to the data dictionary, storage engine, and binary log, or is rolled back, even if the server halts during the operation.

8.0支持原子数据定义语言(DDL)语句。这个特性被称为原子DDL。原子DDL语句将数据字典更新、存储引擎操作和与DDL操作相关联的二进制日志写入到一个单独的原子操作中。该操作要么被提交,并将适用的更改持久化到数据字典、存储引擎和二进制日志中,要么被回滚,即使在操作期间服务器停止。

Note

Atomic DDL is not transactional DDL. DDL statements, atomic or otherwise, implicitly end any transaction that is active in the current session, as if you had done a COMMIT before executing the statement. This means that DDL statements cannot be performed within another transaction, within transaction control statements such as START TRANSACTION ... COMMIT, or combined with other statements within the same transaction.

原子DDL不是事务性DDL。DDL语句(原子的或其他的)隐式结束当前会话中活动的任何事务,就像在执行语句之前执行了COMMIT一样。这意味着DDL语句不能在另一个事务中执行,也不能在事务控制语句中执行,例如START transaction…或在同一事务中与其他语句组合。

Atomic DDL is made possible by the introduction of the MySQL data dictionary in MySQL 8.0. In earlier MySQL versions, metadata was stored in metadata files, nontransactional tables, and storage engine-specific dictionaries, which necessitated intermediate commits. Centralized, transactional metadata storage provided by the MySQL data dictionary removed this barrier, making it possible to restructure DDL statement operations to be atomic.

在MySQL 8.0中引入的MySQL数据字典使原子DDL成为可能。在早期的MySQL版本中,元数据存储在元数据文件、非事务表和特定于存储引擎的字典中,这需要中间提交。由MySQL数据字典提供的集中的、事务性的元数据存储消除了这一障碍,使重新构造DDL语句操作成为可能。

The atomic DDL feature is described under the following topics in this section:

Supported DDL Statements

The atomic DDL feature supports both table and non-table DDL statements. Table-related DDL operations require storage engine support, whereas non-table DDL operations do not. Currently, only the InnoDB storage engine supports atomic DDL.

原子DDL特性既支持表DDL语句,也支持非表DDL语句。表相关的DDL操作需要存储引擎的支持,而非表的DDL操作则不需要。目前,只有InnoDB存储引擎支持原子DDL。

  • Supported table DDL statements include CREATEALTER, and DROP statements for databases, tablespaces, tables, and indexes, and the TRUNCATE TABLE statement.

  • 支持的表DDL语句包括数据库、表空间、表和索引的CREATE、ALTER和DROP语句,以及TRUNCATE table语句。

  • Supported non-table DDL statements include:支持的非表DDL语句包括:

    • CREATE and DROP statements, and, if applicable, ALTER statements for stored programs, triggers, views, and loadable functions.

    • 用于存储程序、触发器、视图和可加载函数的CREATE和DROP语句,以及(如果适用的话)ALTER语句。

    • Account management statements: CREATEALTERDROP, and, if applicable, RENAME statements for users and roles, as well as GRANT and REVOKE statements.

    • 帐户管理语句:用户和角色的CREATE、ALTER、DROP和(如果适用的话)RENAME语句,以及GRANT和REVOKE语句。

The following statements are not supported by the atomic DDL feature:

原子DDL特性不支持以下语句

Atomic DDL Characteristics

原子DDL特点

The characteristics of atomic DDL statements include the following:

原子DDL语句的特点包括:

  • Metadata updates, binary log writes, and storage engine operations, where applicable, are combined into a single atomic operation.

  • 元数据更新、二进制日志写入和存储引擎操作(如果适用的话)被组合成单个原子操作。

  • There are no intermediate commits at the SQL layer during the DDL operation.

  • 在DDL操作期间,SQL层没有中间提交。

  • Where applicable:在适用情况下

    • The state of data dictionary, routine, event, and loadable function caches is consistent with the status of the DDL operation, meaning that caches are updated to reflect whether or not the DDL operation was completed successfully or rolled back.

    • 数据字典、例程、事件和可加载函数缓存的状态与DDL操作的状态一致,这意味着更新缓存以反映DDL操作是否成功完成或回滚

    • The storage engine methods involved in a DDL operation do not perform intermediate commits, and the storage engine registers itself as part of the DDL operation.

    • DDL操作中涉及的存储引擎方法不执行中间提交,存储引擎将自己注册为DDL操作的一部分。

    • The storage engine supports redo and rollback of DDL operations, which is performed in the Post-DDL phase of the DDL operation.

    • 存储引擎支持DDL操作的重做和回滚,这是在DDL操作的Post-DDL阶段执行的。

  • The visible behaviour of DDL operations is atomic, which changes the behavior of some DDL statements. See Changes in DDL Statement Behavior.

  • DDL操作的可见行为是原子的,它改变了一些DDL语句的行为。参见DDL语句行为的更改。

Changes in DDL Statement Behavior

DDL语句行为的变化

This section describes changes in DDL statement behavior due to the introduction of atomic DDL support.

本节描述由于引入原子DDL支持而导致的DDL语句行为的变化。

  • DROP TABLE operations are fully atomic if all named tables use an atomic DDL-supported storage engine. The statement either drops all tables successfully or is rolled back.如果所有命名表都使用原子ddl支持的存储引擎,那么DROP TABLE操作就是完全原子的。该语句要么成功删除所有表,要么回滚。

    DROP TABLE  fails with an error if a named table does not exist, and no changes are made, regardless of the storage engine. This change in behavior is demonstrated in the following example, where the DROP TABLE statement fails because a named table does not exist:不管存储引擎是什么,如果指定的表不存在,并且没有进行任何更改,则DROP TABLE将失败并出现错误。下面的例子演示了这种行为上的改变,其中DROP TABLE语句失败,因为一个命名的表不存在:

    mysql> CREATE TABLE t1 (c1 INT);
    mysql> DROP TABLE t1, t2;
    ERROR 1051 (42S02): Unknown table 'test.t2'
    mysql> SHOW TABLES;
    +----------------+
    | Tables_in_test |
    +----------------+
    | t1             |
    +----------------+

    Prior to the introduction of atomic DDL, DROP TABLE reports an error for the named table that does not exist but succeeds for the named table that does exist:

  • 在引入原子DDL之前,DROP TABLE对于不存在的命名表报告一个错误,但对于存在的命名表报告成功:

    mysql> CREATE TABLE t1 (c1 INT);
    mysql> DROP TABLE t1, t2;
    ERROR 1051 (42S02): Unknown table 'test.t2'
    mysql> SHOW TABLES;
    Empty set (0.00 sec)

    Note

    Due to this change in behavior, a partially completed DROP TABLE statement on a MySQL 5.7 replication source server fails when replicated on a MySQL 8.0 replica. To avoid this failure scenario, use IF EXISTS syntax in DROP TABLE statements to prevent errors from occurring for tables that do not exist.

  • 由于这种行为的改变,当在MySQL 8.0副本上复制时,MySQL 5.7复制源服务器上部分完成的DROP TABLE语句会失败。为了避免这种失败场景,在DROP TABLE语句中使用IF EXISTS语法,以防止不存在的表发生错误。

  • DROP DATABASE is atomic if all tables use an atomic DDL-supported storage engine. The statement either drops all objects successfully or is rolled back. However, removal of the database directory from the file system occurs last and is not part of the atomic operation. If removal of the database directory fails due to a file system error or server halt, the DROP DATABASE transaction is not rolled back.

  • For tables that do not use an atomic DDL-supported storage engine, table deletion occurs outside of the atomic DROP TABLE or DROP DATABASE transaction. Such table deletions are written to the binary log individually, which limits the discrepancy between the storage engine, data dictionary, and binary log to one table at most in the case of an interrupted DROP TABLE or DROP DATABASE operation. For operations that drop multiple tables, the tables that do not use an atomic DDL-supported storage engine are dropped before tables that do.

  • CREATE TABLEALTER TABLERENAME TABLETRUNCATE TABLECREATE TABLESPACE, and DROP TABLESPACE operations for tables that use an atomic DDL-supported storage engine are either fully committed or rolled back if the server halts during their operation. In earlier MySQL releases, interruption of these operations could cause discrepancies between the storage engine, data dictionary, and binary log, or leave behind orphan files. RENAME TABLE operations are only atomic if all named tables use an atomic DDL-supported storage engine.

  • As of MySQL 8.0.21, on storage engines that support atomic DDL, the CREATE TABLE ... SELECT statement is logged as one transaction in the binary log when row-based replication is in use. Previously, it was logged as two transactions, one to create the table, and the other to insert data. A server failure between the two transactions or while inserting data could result in replication of an empty table. With the introduction of atomic DDL support, CREATE TABLE ... SELECT statements are now safe for row-based replication and permitted for use with GTID-based replication.

    On storage engines that support both atomic DDL and foreign key constraints, creation of foreign keys is not permitted in CREATE TABLE ... SELECT statements when row-based replication is in use. Foreign key constraints can be added later using ALTER TABLE.

    When CREATE TABLE ... SELECT is applied as an atomic operation, a metadata lock is held on the table while data is inserted, which prevents concurrent access to the table for the duration of the operation.

  • DROP VIEW fails if a named view does not exist, and no changes are made. The change in behavior is demonstrated in this example, where the DROP VIEW statement fails because a named view does not exist:

    mysql> CREATE VIEW test.viewA AS SELECT * FROM t;
    mysql> DROP VIEW test.viewA, test.viewB;
    ERROR 1051 (42S02): Unknown table 'test.viewB'
    mysql> SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
    +----------------+------------+
    | Tables_in_test | Table_type |
    +----------------+------------+
    | viewA          | VIEW       |
    +----------------+------------+

    Prior to the introduction of atomic DDL, DROP VIEW returns an error for the named view that does not exist but succeeds for the named view that does exist:

    mysql> CREATE VIEW test.viewA AS SELECT * FROM t;
    mysql> DROP VIEW test.viewA, test.viewB;
    ERROR 1051 (42S02): Unknown table 'test.viewB'
    mysql> SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';
    Empty set (0.00 sec)

    Note

    Due to this change in behavior, a partially completed DROP VIEW operation on a MySQL 5.7 replication source server fails when replicated on a MySQL 8.0 replica. To avoid this failure scenario, use IF EXISTS syntax in DROP VIEW statements to prevent an error from occurring for views that do not exist.

  • Partial execution of account management statements is no longer permitted. Account management statements either succeed for all named users or roll back and have no effect if an error occurs. In earlier MySQL versions, account management statements that name multiple users could succeed for some users and fail for others.

    The change in behavior is demonstrated in this example, where the second CREATE USER statement returns an error but fails because it cannot succeed for all named users.

    mysql> CREATE USER userA;
    mysql> CREATE USER userA, userB;
    ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'
    mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
    +-------+
    | User  |
    +-------+
    | userA |
    +-------+

    Prior to the introduction of atomic DDL, the second CREATE USER statement returns an error for the named user that does not exist but succeeds for the named user that does exist:

    mysql> CREATE USER userA;
    mysql> CREATE USER userA, userB;
    ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'
    mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
    +-------+
    | User  |
    +-------+
    | userA |
    | userB |
    +-------+

    Note

    Due to this change in behavior, partially completed account management statements on a MySQL 5.7 replication source server fail when replicated on a MySQL 8.0 replica. To avoid this failure scenario, use IF EXISTS or IF NOT EXISTS syntax, as appropriate, in account management statements to prevent errors related to named users.

Storage Engine Support

Currently, only the InnoDB storage engine supports atomic DDL. Storage engines that do not support atomic DDL are exempted from DDL atomicity. DDL operations involving exempted storage engines remain capable of introducing inconsistencies that can occur when operations are interrupted or only partially completed.

目前,只有InnoDB存储引擎支持原子DDL。不支持原子DDL的存储引擎不支持DDL原子性。涉及豁免存储引擎的DDL操作仍然有可能引入不一致,当操作被中断或仅部分完成时可能会发生这种情况。

To support redo and rollback of DDL operations, InnoDB writes DDL logs to the mysql.innodb_ddl_log table, which is a hidden data dictionary table that resides in the mysql.ibd data dictionary tablespace.

为了支持DDL操作的重做和回滚,InnoDB会将DDL日志写到mysql中。Innodb_ddl_log表,它是一个隐藏的数据字典表,存在于mysql中。数据字典表空间。

To view DDL logs that are written to the mysql.innodb_ddl_log table during a DDL operation, enable the innodb_print_ddl_logs configuration option. For more information, see Viewing DDL Logs.

查看写入mysql的DDL日志。innodb_ddl_log表在DDL操作时,启用innodb_print_ddl_logs配置选项。

Note

The redo logs for changes to the mysql.innodb_ddl_log table are flushed to disk immediately regardless of the innodb_flush_log_at_trx_commit setting. Flushing the redo logs immediately avoids situations where data files are modified by DDL operations but the redo logs for changes to the mysql.innodb_ddl_log table resulting from those operations are not persisted to disk. Such a situation could cause errors during rollback or recovery.

更改mysql的重做日志。不管innodb_flush_log_at_trx_commit设置如何,Innodb_ddl_log表都会立即刷新到磁盘。立即刷新重做日志可以避免数据文件被DDL操作修改而重做日志被更改到mysql的情况。这些操作产生的Innodb_ddl_log表不会持久化到磁盘上。这种情况可能会在回滚或恢复期间导致错误。

The InnoDB storage engine executes DDL operations in phases. DDL operations such as ALTER TABLE may perform the Prepare and Perform phases multiple times prior to the Commit phase.

nnoDB存储引擎分阶段执行DDL操作。像ALTER TABLE这样的DDL操作可能会在Commit阶段之前多次执行Prepare和perform阶段。

  1. Prepare: Create the required objects and write the DDL logs to the mysql.innodb_ddl_log table. The DDL logs define how to roll forward and roll back the DDL operation.准备:创建所需的对象,并将DDL日志写入mysql。innodb_ddl_log表。DDL日志定义如何前滚和回滚DDL操作。

  2. Perform: Perform the DDL operation. For example, perform a create routine for a CREATE TABLE operation.执行:执行DDL操作。例如,为create TABLE操作执行一个create例程。

  3. Commit: Update the data dictionary and commit the data dictionary transaction.Commit:更新数据字典并提交数据字典事务。

  4. Post-DDL: Replay and remove DDL logs from the mysql.innodb_ddl_log table. To ensure that rollback can be performed safely without introducing inconsistencies, file operations such as renaming or removing data files are performed in this final phase. This phase also removes dynamic metadata from the mysql.innodb_dynamic_metadata data dictionary table for DROP TABLETRUNCATE TABLE, and other DDL operations that rebuild the table.Post-DDL:从mysql中重放并删除DDL日志。innodb_ddl_log表。为了确保可以安全地执行回滚,而不会导致不一致,在最后阶段将执行重命名或删除数据文件等文件操作。此阶段还将从mysql中删除动态元数据。innodb_dynamic_metadata数据字典表,用于DROP table、TRUNCATE table和其他重建表的DDL操作。

DDL logs are replayed and removed from the mysql.innodb_ddl_log table during the Post-DDL phase, regardless of whether the DDL operation is committed or rolled back. DDL logs should only remain in the mysql.innodb_ddl_log table if the server is halted during a DDL operation. In this case, the DDL logs are replayed and removed after recovery.

重新播放DDL日志并从mysql中删除。innodb_ddl_log表,无论DDL操作是提交还是回滚。DDL日志应该只保留在mysql中。innodb_ddl_log表,如果服务器在DDL操作期间停止。在这种情况下,DDL日志将重新播放并在恢复后删除。

In a recovery situation, a DDL operation may be committed or rolled back when the server is restarted. If the data dictionary transaction that was performed during the Commit phase of a DDL operation is present in the redo log and binary log, the operation is considered successful and is rolled forward. Otherwise, the incomplete data dictionary transaction is rolled back when InnoDB replays data dictionary redo logs, and the DDL operation is rolled back.

在恢复情况下,当服务器重新启动时,DDL操作可能被提交或回滚。如果在DDL操作的Commit阶段执行的数据字典事务出现在重做日志和二进制日志中,则认为操作成功并前滚。否则,InnoDB重放数据字典重做日志时回滚不完整的数据字典事务,回滚DDL操作。

Viewing DDL Logs

To view DDL logs that are written to the mysql.innodb_ddl_log data dictionary table during atomic DDL operations that involve the InnoDB storage engine, enable innodb_print_ddl_logs to have MySQL write the DDL logs to stderr. Depending on the host operating system and MySQL configuration, stderr may be the error log, terminal, or console window. See Section 5.4.2.2, “Default Error Log Destination Configuration”.

查看写入mysql的DDL日志。innodb_ddl_log数据字典表,在涉及InnoDB存储引擎的原子DDL操作中,使innodb_print_ddl_logs使MySQL将DDL日志写到stderr。根据主机操作系统和MySQL配置,stderr可能是错误日志、终端或控制台窗口。参见5.4.2.2节,“默认错误日志目的地配置”。

InnoDB writes DDL logs to the mysql.innodb_ddl_log table to support redo and rollback of DDL operations. The mysql.innodb_ddl_log table is a hidden data dictionary table that resides in the mysql.ibd data dictionary tablespace. Like other hidden data dictionary tables, the mysql.innodb_ddl_log table cannot be accessed directly in non-debug versions of MySQL. (See Section 14.1, “Data Dictionary Schema”.) The structure of the mysql.innodb_ddl_log table corresponds to this definition:

InnoDB将DDL日志写入mysql。innodb_ddl_log表支持重做和DDL回滚操作。mysql。Innodb_ddl_log表是mysql中隐藏的数据字典表。数据字典表空间。像其他隐藏数据字典表一样,mysql。innodb_ddl_log表在MySQL非调试版本中不能直接访问。(参见14.1节,“数据字典模式”)mysql的结构。Innodb_ddl_log表对应的定义如下:

CREATE TABLE mysql.innodb_ddl_log (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  thread_id BIGINT UNSIGNED NOT NULL,
  type INT UNSIGNED NOT NULL,
  space_id INT UNSIGNED,
  page_no INT UNSIGNED,
  index_id BIGINT UNSIGNED,
  table_id BIGINT UNSIGNED,
  old_file_path VARCHAR(512) COLLATE UTF8_BIN,
  new_file_path VARCHAR(512) COLLATE UTF8_BIN,
  KEY(thread_id)
);
  • id: A unique identifier for a DDL log record.

  • id: DDL日志记录的唯一标识符。

  • thread_id: Each DDL log record is assigned a thread_id, which is used to replay and remove DDL logs that belong to a particular DDL operation. DDL operations that involve multiple data file operations generate multiple DDL log records.

  • thread_id:为每个DDL日志记录分配一个thread_id,用于重放和删除属于特定DDL操作的DDL日志。涉及多个数据文件操作的DDL操作会生成多个DDL日志记录。

  • type: The DDL operation type. Types include FREE (drop an index tree), DELETE (delete a file), RENAME (rename a file), or DROP (drop metadata from the mysql.innodb_dynamic_metadata data dictionary table).

  • type: DDL操作类型。类型包括FREE(删除索引树)、DELETE(删除文件)、RENAME(重命名文件)或drop(从mysql中删除元数据)。Innodb_dynamic_metadata数据字典表)。

  • space_id: The tablespace ID.

  • space_id:表空间ID。

  • page_no: A page that contains allocation information; an index tree root page, for example.

  • page_no:包含分配信息的页面;例如,索引树的根页面。

  • index_id: The index ID.

  • table_id: The table ID.

  • old_file_path: The old tablespace file path. Used by DDL operations that create or drop tablespace files; also used by DDL operations that rename a tablespace.

  • new_file_path: The new tablespace file path. Used by DDL operations that rename tablespace files.

This example demonstrates enabling innodb_print_ddl_logs to view DDL logs written to strderr for a CREATE TABLE operation.

mysql> SET GLOBAL innodb_print_ddl_logs=1;
mysql> CREATE TABLE t1 (c1 INT) ENGINE = InnoDB;
[Note] [000000] InnoDB: DDL log insert : [DDL record: DELETE SPACE, id=18, thread_id=7,
space_id=5, old_file_path=./test/t1.ibd]
[Note] [000000] InnoDB: DDL log delete : by id 18
[Note] [000000] InnoDB: DDL log insert : [DDL record: REMOVE CACHE, id=19, thread_id=7,
table_id=1058, new_file_path=test/t1]
[Note] [000000] InnoDB: DDL log delete : by id 19
[Note] [000000] InnoDB: DDL log insert : [DDL record: FREE, id=20, thread_id=7,
space_id=5, index_id=132, page_no=4]
[Note] [000000] InnoDB: DDL log delete : by id 20
[Note] [000000] InnoDB: DDL log post ddl : begin for thread id : 7
[Note] [000000] InnoDB: DDL log post ddl : end for thread id : 7
上一篇:spring jdbc:initialize-database 启动异常


下一篇:androidX与android.support