## 模块 5：使用在线 DDL 执行在线表结构变更

+ 本模块演示如何在 **TiDB** 中执行**在线表结构变更（DDL 操作）**，同时确保正在运行的**INSERT 任务**继续运行而不中断。这个过程中的一个关键挑战是处理**错误代码 8028**，这种错误发生在表结构变更暂时阻塞事务时。演示展示了一种处理这种情况的稳健方法，允许插入作业在表结构变更期间恢复并继续运行。

+ 本模块包含两个主要操作：

1. **插入作业（`--insert`）**
   + 持续向指定表中插入新记录。
   + 处理可能由于并发 DDL 操作而发生的表结构变更异常（错误代码 **8028**）。
   + 在失败时重试插入操作以维持服务可用性。

2. **表结构修改（`--alter`）**
   + 在插入进行时执行 `ALTER TABLE` 命令以修改表结构。
   + 演示 TiDB 允许**在线表结构变更**，但事务可能会因表结构变更而暂时失败。
   + 确保新表结构成功应用，同时进行中的事务能够相应调整。

> [!TIP]
> **关键实现细节：**
>
> + **处理 TiDB 元数据锁**：脚本**禁用元数据锁定**（`SET GLOBAL tidb_enable_metadata_lock = OFF`）以允许 DDL 变更而不阻塞查询。
> + **自动错误处理**：插入作业**检测错误代码 8028** 并**重试失败的事务**以防止崩溃。
> + **并发执行**：脚本允许在单独的终端中运行**插入作业**和**表结构修改**，模拟数据库更新与进行中事务并存的真实场景。

+ 首先运行插入作业。

  ```bash
  poetry run python mysql_connector_python_demo/online_ddl.py --insert
  ```

  ```output
  Starting insert job on table online_ddl_test
  You can now run ALTER TABLE in another terminal with:
  python online_ddl.py --alter online_ddl_test
  Connected to TiDB: 2nR9s2Y6oh4rkp7.6z3VQEZ4@gateway01.us-west-2.prod.aws.tidbcloud.com:4000 using database test
  Disabled TiDB metadata lock for online DDL operations
  Current setting: tidb_enable_metadata_lock = OFF
  Created table online_ddl_test
  Inserting record 0
  Inserting record 1
  Inserting record 2
  Inserting record 3
  Inserting record 4
  Inserting record 5
  ...
  ```

  ![90%](https://public-pingcap-innovation.s3.us-west-2.amazonaws.com/demo-405/405-online-ddl-0319.jpg)

+ 通过点击 VS Code 中的 `+` 按钮创建一个新终端。

  ![90%](https://public-pingcap-innovation.s3.us-west-2.amazonaws.com/demo-405/405-add-terminal-0319.jpg)

+ 在新终端中运行表结构修改。

  ```bash
  poetry run python mysql_connector_python_demo/online_ddl.py --alter
  ```

  ```output
  Executing ALTER TABLE on online_ddl_test
  Connected to TiDB: 2nR9s2Y6oh4rkp7.6z3VQEZ4@gateway01.us-west-2.prod.aws.tidbcloud.com:4000 using database test
  Table online_ddl_test exists, proceeding with ALTER TABLE
  Executing: ALTER TABLE online_ddl_test ADD COLUMN (ed VARCHAR(10) DEFAULT 'N/A')
  ALTER TABLE completed successfully in 0.39 seconds

  Updated table structure:
    id: int(11)
    k: int(11)
    c: char(120)
    pad: char(60)
    ed: varchar(10)
  ```

  ![90%](https://public-pingcap-innovation.s3.us-west-2.amazonaws.com/demo-405/405-alter-table-0319.jpg)

+ 在 VS Code 中切回第一个终端，观察插入作业将继续运行并显示重试日志。

  ```output
  ...
  Inserting record 105
  Inserting record 106
  Schema mutation encountered, retrying...
  Inserting record 107
  Inserting record 108
  ...
  ```

  ![90%](https://public-pingcap-innovation.s3.us-west-2.amazonaws.com/demo-405/405-error-catch.jpg)

+ 插入 DML 和 DDL 操作都不会被阻塞。
