## 模块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
  rm -f DemoJdbcOnlineDDL.class
  javac -cp mysql-connector-j-9.1.0.jar DemoJdbcOnlineDDL.java  
  sleep 1   
  java -cp :mysql-connector-j-9.1.0.jar DemoJdbcOnlineDDL --insert
  ```

  ```output
  ...
  Inserting record 0
  Inserting record 1
  Inserting record 2
  Inserting record 3
  Inserting record 4
  Inserting record 5
  ...
  ```

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

  ![90%](https://lab-static.pingcap.com/images/2025/7/7/797b653f8fc9a08a362cf618d2fe7fb9ef960fad.jpeg)

+ 在新终端中运行模式修改。

  ```bash
  source env.sh
  java -cp :mysql-connector-j-9.1.0.jar DemoJdbcOnlineDDL --alter
  ```

  ```output
  Executing ALTER TABLE on online_ddl_test
  Connected to TiDB: xxxxxx.xxxxxx@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)
  ```

+ 在VS Code中，切换回第一个终端，我们可以看到插入作业继续运行并显示重试日志。

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

+ 插入DML和DDL操作都没有被阻塞。

+ 您现在可以使用终端中的`CTRL + c`终止正在运行的插入程序。
