AliSQL DDL最佳实践

2026-06-15   访问量:1012


DDLMySQL中最常见的变更动作,MySQL发展至今,DDL能力也在不断增强。本文主要介绍MySQL DDL能力的发展过程,常用的DDL操作说明,并给出AliSQLDDL操作的优化和最佳实践。

DDL能力发展

  • MySQL 5.5及之前:仅支持COPY算法。

    • 执行过程:先创建临时表,然后按行拷贝数据,最后表交换。

    • 限制:DDL执行期间表只读,无法写入数据。

  • MySQL 5.6 & 5.7:支持INPLACE算法。

    • 执行过程:引擎层处理DDL,无需临时表。

    • 优势:DDL执行期间支持读写数据表。

    • 限制:在DDL开始和结束时,可能会短暂锁表(不可读写),且会消耗临时空间。

  • MySQL 8.0、8.4:支持INSTANT算法。

    • 执行过程:仅修改元数据,无需数据拷贝。

    • 优势:秒级完成,显著缓解DDL对业务的影响。

    • 限制:支持的DDL类型有限(加列、删列),在DDL开始和结束时,仍需要短暂持有表上的MDL X锁(不可读写)。

image

说明

所有算法均需在DDL的开始和结束阶段(上图阶段1和阶段3)获取MDL X锁,导致短暂锁表(不可读写),AliSQLMDL锁等待进行了优化,详见AliSQL DDL相关优化功能

MySQL常用DDL操作说明

MySQL支持在执行DDL操作时指定算法,若不指定,MySQL默认根据DDL操作类型选择最佳算法。以下为常见操作的执行逻辑及影响(默认InnoDB引擎)。

表操作

列操作

索引操作

特殊情况说明

DDL操作

DDL命令

默认算法及是否支持修改

DDL执行期间读写属性

可能影响说明

重命名表

RENAME

支持修改算法,默认值:

  • 5.6、5.7:INPLACE

  • 8.0、8.4:INSTANT

读写

仅修改元数据,无影响。

重建表

OPTIMIZE / ALTER ENGINE

不支持修改算法,5.6、5.7、8.08.4默认值:INPLACE。

读写

说明

AliSQL 8.0、8.4数据归档期间表只读不可写。

  • 重建表会进行数据拷贝,需预留磁盘空间。

  • 大表耗时长。

  • 可能导致备库和只读实例复制延迟。

更新统计信息

ANALYZE

不支持修改算法。

读写

仅更新统计信息,但某些场景可能导致业务阻塞,详见特殊情况说明页签里的ANALYZE TABLE的阻塞场景。

修改字符集

CONVERT CHARSET

  • 5.6、5.7不支持修改算法,默认值COPY。

  • 8.0、8.4:支持修改算法,默认值COPY,仅特殊场景支持INPLACE,详见特殊情况说明页签里的修改字符集(CONVERT CHARSET)时使用INPLACE算法。

只读,无法进行写操作。

  • 会拷贝数据到临时表,需预留磁盘空间。

  • 大表耗时长。

  • 可能导致备库和只读实例复制延迟。

修改表备注

ALTER COMMENT

不支持修改算法,5.6、5.7、8.08.4默认值:INPLACE。

读写

仅修改元数据,无影响。

DDL执行时间评估

方式一:基于Performance Schema(PFS)评估

MySQL 5.7版本开始在 PFS加入了DDL相关Stage统计信息,可以通过processlistP_S库下的events_stages_current表查看DDL进度,并且评估剩余时间。

  • 适用场景:DDL执行中需实时监控进度。

  • 查询语句:

     

    SELECT * FROM information_schema.processlist WHERE ID = <替换为实际ID>;SELECT THREAD_ID, EVENT_ID, EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED,(WORK_COMPLETED/WORK_ESTIMATED)*100 AS PROGRESS  
    FROM performance_schema.events_stages_current WHERE THREAD_ID = <替换为实际ID>;

    说明

    执行SHOW Processlist命令根据执行的SQL获取ID。

  • 示例:本地Sysbench 10 GB的表,查询结果TIME=116PROGRESS=83.9961%,如下图所示:

    image

    • 计算时间 = TIME / PROGRESS = 116 / (83.9961%) = 138.1 s

    • 实际执行时间:2 min 3.14 s = 123.14 s

      image

方式二:基于表空间大小评估

  • 适用场景:无需开启PFS(消耗内存且会有性能影响,RDS MySQL默认关闭)的估算。

  • 步骤:

    • 云盘实例(高性能云盘和ESSD云盘):按照30~60 MB/s的速度进行估算。

    • 高性能本地盘实例:按照50~100 MB/s的速度进行估算。

      说明

      30~60 MB/s50~100 MB/s的速度是根据实例的IO能力估算的值,实际可能会有偏差。

    1. 查询表大小:

       

      SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA =  <替换为实际的数据库名> AND TABLE_NAME = <替换为实际的表名>;
    2. 根据查询到的DATA_LENGTH大小,直接估算DDL的时间,以OPTIMIZE TABLE操作为例:

    3. (可选)索引影响:如果表存在很多二级索引,还需考虑二级索引排序和构建的时间,按主表速度的1/3估算索引构建时间。

  • 示例:本地Sysbench 10 GB的表,查询结果如下:

    image

    • 计算时间 = DATA_LENGTH / 1024 / 1024 / 100 + INDEX_LENGTH / 1024 / 1024 / 100 * 3 = 10270785536 / 1024 / 1024 / 100 + 665829376 / 1024 / 1024 / 100 * 3 = 117 s

    • 实际执行时间:2 min 3.14 s = 123.14 s

      image

AliSQL DDL最佳实践

基本原则

  1. DDL是变更操作,尽量避开业务高峰。

  2. 支持INSTANT算法的DDL,或其他仅修改元数据的DDL,可以放心执行(为避免操作开始和结束阶段无法获取MDL X锁,仍需重点关注慢查询和大事务)。

  3. 只支持COPY算法的DDL,执行过程中表只读,无法进行写操作,需要谨慎执行。

  4. 其他支持INPLACE算法的DDL,执行过程中表可以读写,但是需要综合评估执行时间、空间占用,以及可能导致的复制延迟问题。

AliSQL DDL相关优化功能

  • 大表删除优化

    • 功能:异步清理大文件,避免文件系统抖动。

    • 参数:innodb_data_file_purge=ON(默认开启)。

  • Buffer Pool管理优化

    • 功能:减少DDL的执行耗时,降低DDL操作带来的性能影响。

    • 参数:loose_innodb_rds_faster_ddl=ON(需手动开启)。

  • 秒级加列

    • 功能:元数据变更,无需重建表。

    • 参数:loose_innodb_instant_ddl_enabled=ON(MySQL 8.0版本默认开启,5.7及以下版本需手动开启)。

  • 其他优化

    • AHI清理优化:优化删除表和索引过程中AHI清理导致的性能问题。参数:innodb_rds_drop_ahi_ahead,默认为OFF。

    • 唯一索引冲突优化:优化DDL期间唯一索引冲突导致DDL失败的问题。

    • MDL锁等待逻辑优化:将MDL X锁的阻塞式等待优化为非阻塞式等待,解决了DDL长期拿不到MDL锁导致业务面积性阻塞的问题。

    • ANALYZE TABLE优化:解决了MySQL 5.7 版本ANALYZE TABLE可能导致业务阻塞的问题。

    • Parallel DDL:修复DDL性能回退问题。

相关文档


热门文章
更多>