集群中的DDL处理原理与优化
TiKV 集群设有两个专门的队列:general job queue 和 add index job queue,分别用于处理逻辑 DDL 和物理 DDL。DDL Owner 按照先入先出的原则处理 DDL Job,并且每次只能执行一个同种类型(逻辑或物理)的 DDL 任务。
DDL处理特点
- 在线变更支持:所有DDL变更都支持在线进行,不会影响正常的数据访问。
-
DDL分类:
- 逻辑DDL语句:这类语句仅修改数据库对象的元数据,而不处理变更对象所存储的数据。例如,修改列名、增加字段、扩展字段长度等。逻辑DDL在TiDB中执行速度极快,瞬间即可完成,对业务完全没有影响。
- 物理DDL语句:这类语句不仅会修改变更对象的元数据,还会修改变更对象所存储的用户数据。例如,为表创建索引、减小字段长度、修改字段类型等。物理DDL的执行耗时与表数据量有关,数据重新组织(REORG)过程中可能会对业务性能产生一定影响,但不会造成业务中断或报错。
操作时间评估
- 创建/删除数据库和表:毫秒级
- 清空表:毫秒级
- 添加和删除列:毫秒级
- 扩充字段长度:毫秒级
- 删除索引:毫秒级
- 添加索引:取决于数据量大小
- 修改字段类型:取决于数据量大小
- 缩小字段长度:取决于数据量大小
DDL详情查看
通过执行ADMIN SHOW DDL JOBS
命令,可以查看DDL作业的详细信息。其中,关键字段说明如下:
- JOB_ID:每个DDL操作对应一个唯一的DDL作业ID。
- DB_NAME:数据库名。
- TABLE_NAME:表名。
- JOB_TYPE:具体的DDL类型。
-
SCHEMA_STATE:schema的当前状态,根据DDL操作类型有所不同。例如,
none
表示不存在,delete only
、write only
、delete reorganization
、write reorganization
表示正在进行的数据重组过程,public
表示存在且可用。 - SCHEMA_ID:执行DDL操作的数据库的ID。
- TABLE_ID:执行DDL操作的表的ID。
- ROW_COUNT:执行添加索引操作时,当前已经添加完成的数据行数。
- START_TIME:DDL操作的开始时间。
-
STATE:DDL操作的状态,例如
none
表示已进入DDL作业队列但尚未执行,running
表示操作正在执行,synced
表示操作已成功执行等。
DDL执行可能慢的原因
- DDL操作是串行执行的。
- 可能存在MDL(元数据锁)锁等待。
- 集群资源使用率高或不可用。
元数据锁( V6.3.0)
1、引入了mysql.tidb_mdl_view
视图,用于查看当前阻塞的DDL的相关信息。如果发现DDL操作被阻塞,可以考虑通过KILL
会话来解决相关问题。但请谨慎操作,确保不会中断重要的数据操作。
2、online DDL算法引入了元数据锁特性,可能导致生产环境频繁出现DDL被MDL锁阻塞的情况。如果需要关闭元数据锁,可以将系统变量tidb_enable_metadata_lock
设置为OFF
索引加速(v6.3.0)
-
tidb_ddl_disk_quota
:用于设置创建索引的回填过程中本地存储空间的使用限制。 -
tidb_ddl_enable_fast_reorg
:控制是否开启添加索引加速功能,以提升创建索引回填过程的速度。对于数据量较大的表,开启该变量可以带来一定的性能提升。
要验证已经完成的ADD INDEX
操作是否使用了添加索引加速功能,可以执行ADMIN SHOW DDL JOBS
语句,并查看JOB_TYPE
一列中是否含有ingest
字样。如果含有,则表示该操作使用了添加索引加速功能。
新特性(v7.5.0)
- 支持并行运行多个
ADD INDEX
语句。 - DDL支持暂停和恢复。
网友评论