pt-osc修改外键内部是如何处理的?

  

在讲解pt-osc内部处理流程前,我们先通过下面的例子,看看重命名交换表后,子表的信息。

——创建一个父表   创建表的父母(   id int (11) NOT NULL auto_increment,   parent_id int,   主键(id),   关键IX_parent_id (parent_id)   )引擎=InnoDB;      ——创建一个子表,外键是child_id,和父表parent_id做关联   创建表的孩子(   id int (11) NOT NULL auto_increment,   child_id int(11)默认为空,   主键(id),   关键IX_child_id (child_id),   外键(child_id)引用父(parent_id)   )引擎=InnoDB;      ——把父表改个名   重命名表家长parent_1;

此时子表会自动执向新的父表表名,如下面所示:

显示创建表子\ G      创建表的孩子(   id int (11) NOT NULL AUTO_INCREMENT,   child_id int(11)默认为空,   主键(id),   团队IX_child_id (child_id),   约束child_ibfk_1外键(child_id)引用parent_1 (parent_id)   )引擎=InnoDB的默认字符集=utf8


现在我们要向父表添加一个字段名称varchar (200)

用pt-osc工具执行,通常内部的执行过程是:

1)创建一个临时表_parent_new
2)在临时表_parent_new中添加名字字段
3)在原表上父母定义触发器,以便对原始表上的数据所做的更改也将应用于临时表_parent_new中
4)将数据从原表父母复制到_parent_new。
5)交换名字重命名表家长_parent_old _parent_new父母

6)删除原表删除表_parent_old

7)删除增删改三个触发器


那么最危险的是重命名交换名字后,子表的外键会执向_parent_old,并不会变成父母,这将带来数据不一致的后果。


固,pt-osc增加了——alter-foreign-keys-method参数,默认是drop_swap,它的执行过程跟刚才就有些区别了。

前4步还是一样,第5步开始,变成

5)设置FOREIGN_KEY_CHECKS=;#关闭外键检查

6)交换名字重命名表家长_parent_old

7)删除表_parent_old

8)交换名字重命名表_parent_new _parent_old, _parent_old父;

9)删除增删改三个触发器

10)设置FOREIGN_KEY_CHECKS=,

第7步如果表大,删除的速度较慢的话(第8步不会执行),业务会受影响,这也是比较危险的。


如果修改为rebuild_constraints,它的执行过程是:

交换名字

重命名表家长_parent_old _parent_new父母

(这一步保持和原先一样)

1)将子表外键删除,重新关联父表父母

ALTER table孩子外键child_id下降,添加约束child_ibfk_1外键(child_id)引用父(parent_id)

注:这一步会采用算法=原地算法,不会锁表,支持并发DML。

2)删除原表删除表_parent_old

3)删除增删改三个触发器


设置为汽车,如果子表中的行数很少,则使用rebuild_constraints;否则转换为drop_swap。



pt-osc修改外键内部是如何处理的?