文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  原子資料定義語句支援

15.1.1 原子資料定義語句支援

MySQL 9.0 支援原子資料定義語言 (DDL) 語句。此功能稱為原子 DDL。原子 DDL 語句將與 DDL 操作相關的資料字典更新、儲存引擎操作和二進制日誌寫入組合為單一的原子操作。該操作會被提交,並將適用的變更保存到資料字典、儲存引擎和二進制日誌,或者會被回滾,即使伺服器在操作過程中停止。

注意

原子 DDL 不是交易式 DDL。 DDL 語句,無論是否為原子語句,都會隱式地結束目前工作階段中任何活動的交易,就像您在執行語句之前執行了COMMIT一樣。這表示 DDL 語句無法在其他交易內執行,也無法在交易控制語句(例如 START TRANSACTION ... COMMIT)內執行,或與同一交易中的其他語句組合。

原子 DDL 是透過 MySQL 資料字典實現的,該字典提供集中的交易式元資料儲存。

原子 DDL 功能在本節的以下主題中說明

支援的 DDL 陳述式

原子 DDL 功能支援表格和非表格 DDL 陳述式。與表格相關的 DDL 操作需要儲存引擎支援,而與非表格相關的 DDL 操作則不需要。目前,只有 InnoDB 儲存引擎支援原子 DDL。

  • 支援的表格 DDL 陳述式包括資料庫、表格空間、表格和索引的 CREATEALTERDROP 陳述式,以及 TRUNCATE TABLE 陳述式。

  • 支援的非表格 DDL 陳述式包括

    • 預存程式、觸發程序、檢視和可載入函式的 CREATEDROP 陳述式,以及在適用的情況下,ALTER 陳述式。

    • 帳戶管理陳述式:使用者和角色的 CREATEALTERDROP,以及在適用的情況下,RENAME 陳述式,以及 GRANTREVOKE 陳述式。

下列陳述式不支援原子 DDL 功能

原子 DDL 特性

原子 DDL 陳述式的特性包括下列項目

  • 中繼資料更新、二進位記錄寫入和儲存引擎操作(如適用)會合併為單一原子操作。

  • 在 DDL 操作期間,SQL 層沒有中間認可。

  • 在適用的情況下

    • 資料字典、常式、事件和可載入函式快取的狀態與 DDL 操作的狀態一致,這表示快取會更新,以反映 DDL 操作是否已成功完成或復原。

    • DDL 操作中涉及的儲存引擎方法不會執行中間認可,並且儲存引擎會將自身註冊為 DDL 操作的一部分。

    • 儲存引擎支援 DDL 操作的重做和復原,這會在 DDL 操作的 Post-DDL 階段執行。

  • DDL 操作的視覺行為是原子性的。

儲存引擎支援

目前,只有 InnoDB 儲存引擎支援原子 DDL。不支援原子 DDL 的儲存引擎會免除 DDL 原子性。涉及免除的儲存引擎的 DDL 操作仍然會引入在操作中斷或僅部分完成時可能發生不一致的情況。

為了支援 DDL 操作的重做和復原,InnoDB 會將 DDL 記錄寫入 mysql.innodb_ddl_log 資料表中,此資料表是位於 mysql.ibd 資料字典表格空間中的隱藏資料字典表格。

若要檢視在 DDL 操作期間寫入 mysql.innodb_ddl_log 資料表的 DDL 記錄,請啟用 innodb_print_ddl_logs 組態選項。如需詳細資訊,請參閱 檢視 DDL 記錄

注意

mysql.innodb_ddl_log 資料表所做的變更的重做記錄會立即刷新到磁碟,無論 innodb_flush_log_at_trx_commit 設定為何。立即刷新重做記錄可避免因 DDL 操作而修改資料檔案,但對 mysql.innodb_ddl_log 資料表所做的變更的重做記錄並未持續保存到磁碟的情況。這種情況可能會在復原或還原期間造成錯誤。

InnoDB 儲存引擎會分階段執行 DDL 操作。在 Commit 階段之前,ALTER TABLE 等 DDL 操作可能會多次執行 PreparePerform 階段。

  1. Prepare:建立必要的物件,並將 DDL 記錄寫入 mysql.innodb_ddl_log 資料表。DDL 記錄定義如何向前復原和向後復原 DDL 操作。

  2. Perform:執行 DDL 操作。例如,針對 CREATE TABLE 操作執行建立常式。

  3. Commit:更新資料字典並認可資料字典交易。

  4. Post-DDL:從 mysql.innodb_ddl_log 資料表中重播並移除 DDL 記錄。為了確保在不引入不一致的情況下安全地執行復原,在此最後階段執行檔案操作,例如重新命名或移除資料檔案。此階段也會從 mysql.innodb_dynamic_metadata 資料字典表格中移除 DROP TABLETRUNCATE TABLE 以及其他重建表格的 DDL 操作的動態中繼資料。

無論 DDL 操作是認可還是復原,DDL 記錄都會在 Post-DDL 階段期間從 mysql.innodb_ddl_log 資料表中重播並移除。如果伺服器在 DDL 操作期間停止,則 DDL 記錄應只保留在 mysql.innodb_ddl_log 資料表中。在此情況下,DDL 記錄會在還原後重播並移除。

在還原情況下,重新啟動伺服器時,可能會認可或復原 DDL 操作。如果在重做記錄和二進位記錄中存在 DDL 操作的 Commit 階段期間執行的資料字典交易,則會將操作視為成功並向前復原。否則,當 InnoDB 重播資料字典重做記錄時,會復原不完整的資料字典交易,並且也會復原 DDL 操作。

檢視 DDL 記錄

若要檢視在涉及 InnoDB 儲存引擎的原子 DDL 操作期間寫入 mysql.innodb_ddl_log 資料字典表格的 DDL 記錄,請啟用 innodb_print_ddl_logs,讓 MySQL 將 DDL 記錄寫入 stderr。根據主機作業系統和 MySQL 組態,stderr 可能是錯誤記錄、終端機或主控台視窗。請參閱 第 7.4.2.2 節,〈預設錯誤記錄目的地組態〉

InnoDB 會將 DDL 記錄寫入 mysql.innodb_ddl_log 資料表中,以支援 DDL 操作的重做和復原。mysql.innodb_ddl_log 資料表是位於 mysql.ibd 資料字典表格空間中的隱藏資料字典表格。與其他隱藏資料字典表格一樣,無法在非偵錯版本的 MySQL 中直接存取 mysql.innodb_ddl_log 資料表。(請參閱 第 16.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 utf8mb4_bin,
  new_file_path VARCHAR(512) COLLATE utf8mb4_bin,
  KEY(thread_id)
);
  • id:DDL 記錄的唯一識別碼。

  • thread_id:每個 DDL 記錄都會指派一個 thread_id,此識別碼用於重播和移除屬於特定 DDL 操作的 DDL 記錄。涉及多個資料檔案操作的 DDL 操作會產生多個 DDL 記錄。

  • type:DDL 操作類型。類型包括 FREE(卸載索引樹狀結構)、DELETE(刪除檔案)、RENAME(重新命名檔案)或 DROP(從 mysql.innodb_dynamic_metadata 資料字典表格中卸載中繼資料)。

  • space_id:表格空間 ID。

  • page_no:包含配置資訊的頁面;例如,索引樹狀結構根頁面。

  • index_id:索引 ID。

  • table_id:表格 ID。

  • old_file_path:舊表格空間檔案路徑。由建立或卸載表格空間檔案的 DDL 操作使用;也由重新命名表格空間的 DDL 操作使用。

  • new_file_path:新表格空間檔案路徑。由重新命名表格空間檔案的 DDL 操作使用。

此範例示範啟用 innodb_print_ddl_logs 以檢視為 CREATE TABLE 操作寫入 strderr 的 DDL 記錄。

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