非阻塞改表工具:pt-online-schema-change

pt-osc使用场景

事务A:执行一个非常大的查询
事务B:执行了DDL操作

结果

事务A执行查询时会持有MDL锁,而事务B同样也需要MDL锁,但事务A在进行大查询,所以导致事务B后的所有操作都会被堵塞

解决方案

该情况常见于大表热表的改表,可使用pt-online-schema-change工具解决

pt-osc原理

执行流程

1、相关环境参数检查
2、检查该表格是否存在
3、show create table tbosc
4、create table _tbosc_new
5、alter table _tbosc_new
6、创建删除触发器 pt_osc_dbddl_tbosc_del (如果数据修改的时候,还没有拷贝过来,修改后再拷贝则是覆盖,正确;如果是已经拷贝过来,再修改,也是正确,这里同时会检查是否具有主键或者唯一索引,如果都没有,这一步会报错,提示The new table dbosc._tbosc_new does not have a PRIMARY KEY or a unique index which is required for the DELETE trigger.)
7、创建更新触发器 pt_osc_dbddl_tbosc_upd
8、创建插入触发器 pt_osc_dbddl_tbosc_ins
9、按块拷贝数据到新表,拷贝过程对数据行持有S锁
10、analyze 新表
11、rename表名:

  • RENAME TABLE dbddl.tbosc TO dbddl._tbosc_old
  • dbddl._tbosc_new TO dbddl.tbosc

12、删除旧表
13、删除新表上的删除、更新、插入触发器

DDL期间DML

  • DDL过程采用Copy Table To New Table的方式,新建一个表格,然后在原表上创建3个触发器:DELETE\UPDATE\INSERT触发器,一旦新表,拷贝数据到新表的过程中,如果原表数据发生变化,则会通过触发器更新到新表上。
  • INSERT原表的时候,触发器根据其主键ID把新纪录INSERT到新表上;
  • UPDATE原表的时候,触发器根据其主键ID判断新旧ID是否一致,如果一致则删除,然后在REPLACE INTO新纪录到新表
  • DELETE原表的时候,触发器根据其主键ID直接删除行记录

如果数据修改的时候,还没有拷贝到新表,修改后再拷贝,虽然重复覆盖,但是数据也没有出错;如果是数据已经拷贝,原表发生修改,这时触发器同步修改数据,两种情况下都保证了数据的一致性

  • 创建新表后,按照每一个chunk的大小拷贝数据到新表,每次SELECT都是share mode,带S锁,但是每个chunk都比较小,所以锁时间不大
  • 最后数据拷贝结束,会有一个rename操作,这个操作过程中,是不支持DML操作的,但其速度很快,不会造成长时间锁表情况
  • 该工具会设置该DDL操作的锁等待超时为1s,当出现异常的时候,会是ALTER操作异常,而不是其他业务操作异常,这样可以最大程度的不影响其他事务的进行

执行期间的性能影响

  • 总体而言,对数据库的锁影响降低到了最小,执行期间允许DML操作
  • 但是注意,任何DDL SQL在这里,都是转换成copy table to new table的形式,这个过程中,会极大占用磁盘的IO跟CPU资源,同时跟住从延时带来一定的影响,还是那句老话,重复了解DDL的影响程度后,再选择合适时机执行
  • copy data过程中,如果主从延迟异常超过 max-lag则停止copy data,等待主从延迟恢复,默认为1min,可以通过--max-lag设置
  • 检测到服务器负载异常,也会停止操作,可以通过 --max-load,--critical-load设置

限制情况

  • 表格必须带有主键或者唯一索引

pt-osc唯一约束的校验逻辑代码:

SELECT IF(COUNT(DISTINCT `fields`) = COUNT(*)

当索引涉及的字段存在null的情况,执行DISTINCT时字段会被清理,count时不会包括null行,导致前置的索引参数检查发生异常,终止执行,返回报错:
No, the desired unique index contains duplicated values. There will be data loss

  • copy data过程中,如果主从延迟异常超过 max-lag则停止copy data,等待主从延迟恢复,默认为1s,可以通过--max-lag设置
  • 检测到服务器负载异常,也会停止操作,可以通过 --max-load,--critical-load设置
  • 设置操作的锁等待超时为1s,当出现异常的时候,ALTER操作异常,而不是其他业务操作异常,这样可以最大程度的不影响其他事务的进行
  • 默认情况下,存在 被外键引用的表格是不支持ALTER操作的,除非手动指定参数--alter-foreign-keys-method
  • 不支持修改 Percona XtraDB Cluster (PXC)上节点的 myisam表格
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值