标签:rename pt parent 外键 KEY child table osc id
在讲解pt-osc内部处理流程前,我们先通过下面的例子,看看rename交换表后,子表的信息。
-- 创建一个父表 CREATE TABLE parent ( id int(11) NOT NULL auto_increment, parent_id int, PRIMARY KEY (id), KEY IX_parent_id (parent_id) ) ENGINE=InnoDB; -- 创建一个子表,外键是child_id,和父表parent_id做关联 CREATE TABLE child ( id int(11) NOT NULL auto_increment, child_id int(11) default NULL, PRIMARY KEY (id), KEY IX_child_id (child_id), FOREIGN KEY (child_id) REFERENCES parent (parent_id) ) ENGINE=InnoDB; -- 把父表改个名 rename table parent to parent_1;
此时子表会自动执向新的父表表名,如下面所示:
show create table child\G CREATE TABLE child ( id int(11) NOT NULL AUTO_INCREMENT, child_id int(11) DEFAULT NULL, PRIMARY KEY (id), KEYI IX_child_id (child_id), CONSTRAINT child_ibfk_1 FOREIGN KEY (child_id) REFERENCES parent_1 (parent_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
现在我们要向父表添加一个字段name varchar(200)
用pt-osc工具执行,通常内部的执行过程是:
1)创建一个临时表_parent_new
2)在临时表_parent_new中添加name字段
3)在原表parent上定义触发器,以便对原始表上的数据所做的更改也将应用于临时表_parent_new中
4)将数据从原表parent复制到_parent_new。
5)交换名字rename table parent to _parent_old, _parent_new to parent
6)删除原表 drop table _parent_old
7)删除增删改三个触发器
那么最危险的是rename交换名字后,子表的外键会执向_parent_old,并不会变成parent,这将带来数据不一致的后果。
固,pt-osc增加了--alter-foreign-keys-method参数,默认是drop_swap,它的执行过程跟刚才就有些区别了。
前4步还是一样,第5步开始,变成
5)set FOREIGN_KEY_CHECKS=OFF; #关闭外键检查
6)交换名字rename table parent to _parent_old
7)drop table _parent_old
8)交换名字 rename table _parent_new to _parent_old, _parent_old to parent;
9)删除增删改三个触发器
10)set FOREIGN_KEY_CHECKS=ON;
第7步如果表大,删除的速度较慢的话(第8步不会执行),业务会受影响,这也是比较危险的。
如果修改为rebuild_constraints,它的执行过程是:
交换名字
rename table parent to _parent_old, _parent_new to parent
(这一步保持和原先一样)
1)将子表外键删除,重新关联父表parent
ALTER TABLE child DROP FOREIGN KEY child_id, ADD CONSTRAINT child_ibfk_1 FOREIGN KEY (child_id) REFERENCES parent (parent_id)
注:这一步会采用ALGORITHM=INPLACE算法,不会锁表,支持并发DML。
2)删除原表 drop table _parent_old
3)删除增删改三个触发器
如果设置为auto,如果子表中的行数很少,则使用rebuild_constraints; 否则转换为drop_swap。
标签:rename,pt,parent,外键,KEY,child,table,osc,id 来源: https://blog.51cto.com/hcymysql/2448575
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。