onlineddl
分类
copy
- 删除主键
- 修改列数据类型
- 更改列长度(减少)
- 增加字符串列长度(字节编码长度变更时)
inplace
-
rebuilding
- 添加主键
- 增加索引
- 增加列
- 重建表
-
norebuilding
- 增加和删除二级索引 重建的是索引数据
- 重命名列
- 增加和删除列默认值 **
- 扩展列大小 ** 没有更改字节编码长度,如alter table tab modify column col varchar(60); 字符个数<85 都是瞬间完成
- 添加和删除外键
- 重命名表
执行过程
copy方式
- 1 锁表,期间DML不可并行执行
- 2 生成临时表,更改表结构
- 3 拷贝数据到临时表
- 4 重命名表
- 5 删除临时表
- 6 释放锁
inplace方式
-
准备阶段
- 申请元数据锁
- innodb内部创建中转表
- 申请row log用于记录执行阶段的dml日志
-
执行阶段
- 释放mdl排它锁,允许dml操作
- 拷贝数据到临时文件
- 拷贝过程中产生的dml操作记录row log
-
提交阶段
- 升级mtl排它锁,不允许dml
- 应用增量row log (此时阻塞dml)
- 重命名,产出中转文件
- 提交事务释放锁
可选参数
algorithm
-
copy
- 执行时不允许dml
-
inplace
- 允许dml
-
default
- mysql自动选择使用哪个
lock
-
exclusive
- 整个表加x锁,不允许dml
-
shared
- 表加s锁,允许dml
-
none
- 不添加任何锁
-
default
- mysql自动选择
相关工具
onlineddl问题
- 不支持所有的ddl操作(copy方式) 如增加列长度
- 仍然存在排他锁,有锁等待的风险
- 有可能造成主从延迟
- 执行后不能暂停,只能中断
ptosc
-
执行过程
- 建立一个中间表tablename_new
- 中间表做ddl操作(例如增加列)
- 原先的表建立增删改的触发器
- 拷贝数据到中间表***关键点:以chunk的方式拷贝,对正在拷贝的数据加lock in share mode 锁,正在拷贝的这部分数据是不能修改和删除的 ***
- 改名 删除旧表
-
限制
- 原表需要有主键或者唯一索引
- 原表不能有触发器
- 操作失败不会清理中间表,触发器也存在容易导致问题*
- 表有外键,问题多复杂
- 部分复制的情况会导致失败,因为没有复制中间表
ghost
-
执行过程
- 新建一张ghost表,结构与源表相同
- 新表执行ddl
- 拷贝数据到新表
- 应用增量binlog到新表(应用的过程中是单线程并且锁表)
- 改名
-
限制
- 单线程应用binlog性能较差
其他操作
flush tables
-
过程
- 关闭所有打开的表
- 强制关闭所有正在使用的表
- 刷新查询缓存和预准备语句缓存
-
影响
- flush table 会等待所有的sql执行完成(dml和ddl还有select语句)
- flush table 等待sql执行完的过程中,会阻塞所有这些正在执行sql涉及到的表 **
- flush tables操作可认为是{tables}所有表的表级排他锁,会阻塞其他会话关于{tables}表上的所有操作
flush tables with read lock
- 等待正在运行的所有语句执行结束
- 当前执行的sql涉及到的表,对这些表的新请求都会阻塞
- 当前sql执行后,查询可以执行,其他操作需要解锁后才能操作