# 执行DDL

![`smart`](DDLExecution01_aa_003_20220512.png)

-----------------------------------------------------------
TiDB 支持在线 DDL，这意味着 DDL 操作不会锁表，而且 DML 语句也不会被阻塞。

首先，整个 TiDB 只允许一个 TiDB 服务器同时执行 DDL 操作。每个 TiDB 服务器都有一个 `Worker` 模块，负责处理 DDL 操作，只有当当前 TiDB 服务器的角色是 `Owner` 时才会启用。如果 TiDB 中有多个 TiDB 服务器，这些 TiDB 服务器会轮流（通过选举）在固定时间成为 `Owner` 角色，这被称为任期。当 TiDB 服务器处于 `Owner` 角色和任期时，其 `Worker` 模块可以处理 DDL 操作。数据库的当前 `Owner` 角色信息被持久化到 PD，`Worker` 模块可以检查其所在的 TiDB 服务器是否当前处于 `Owner` 角色。`Owner` 的任期到期后，PD 会发起选举来选择新的 `Owner`。

其次，除了`Worker`模块外，还有`Load Schema`模块，用于在当前TiDB服务器成为`Owner`角色后加载最新的模式信息，以便当前`Owner`角色TiDB服务器可以拥有最新的模式信息。

最后，Start Job 模块负责接收 DDL 请求，为 DDL 操作分配 ID，并且在这里我们称每个分配了 ID 的 DDL 操作为 Job。

总之，DDL操作的第一部分可以总结为：

1. DDL 语句从客户端发送到 TiDB 服务器，服务器解析和编译它们以生成执行计划，这个过程与 DML 语句相同。

2. Start Job 模块封装了 DDL 操作并将其持久化到 TiKV。之后，Start Job 将做另一项工作，即通知它所在的 TiDB 服务器的 `Worker` 模块在 TiKV 中执行作业。然后，`Worker` 首先确定它所在的 TiDB 服务器是否具有所有者角色，如果是，它将执行，如果不是，它将放弃。

3. 如果Start Job所在的TiDB服务器不是`Owner`角色，那么我们只能等待TiDB数据库中的`Owner`角色的TiDB服务器定期检查队列中的任务，然后Job才会被处理。

