工具简介
pt-osc模仿MySQL内部的改表方式进行改表,但整个改表过程是通过对原始表的拷贝来完成的,即在改表过程中原始表不会被锁定,并不影响对该表的读写操作。
首先,osc创建与原始表相同的不包含数据的新表并按照需求进行表结构的修改,然后将原始表中的数据按chunk大小逐步拷贝到新表中,当拷贝完成后,会自动同时修改原始表和新表的名字并默认将原始表删除。
pt-online-schema-change原理
1、如果存在外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,做相应设置的处理。
2、创建一个新的表,表结构为修改后的数据表,用于从源数据表向新表中导入数据。
3、创建触发器,用于记录从拷贝数据开始之后,对源数据表继续进行数据修改的操作记录下来,用于数据拷贝结束后,执行这些操作,保证数据不会丢失。
4、拷贝数据,从源数据表中拷贝数据到新表中。
5、修改外键相关的子表,根据修改后的数据,修改外键关联的子表。
6、rename源数据表为old表,把新表rename为源表名,并将old表删除。
7、删除触发器。
这个过程中有两个问题需要注意:
1. 触发器
因为整个过程是在线的,为了将改表过程中对原始表的更新同时更新到新表上,会创建相应的触发器,每当发生针对原始表的增删改操作,就会触发对新表的相应的操作。所以原始表上不能有其他触发器,即如果原始表上存有触发器,OSC会罢工的。
2. 外键
外键使改表操作变得更加复杂,如果原始表上有外键的话,自动rename原始表和新表的操作就不能顺利进行,必须要在数据拷贝完成后将外键更新到新表上,该工具有两种方法来支持这个操作,具体使用参数(--alter-foreign-keys-method)实现。
--alter-foreign-keys-method
外键改表前后必须持续的链接正确的表,当该工具rename原始表并用新表来取代原始表时,外键必须正确更新到新表上,并且原始表中的外键不再生效
有两种方法来实现这个目的,具体参数有四:
(1)auto
自动决定采用哪个方法,如果可以就采用rebuild_constraints,如果不可以就采用drop_swap
(2)rebuild_constraints
该方法采用alter table来drop并re-add链接新表的外键。除非相关的子表太大使得alter过程花费时间过长,一般都采用该方法。
这里的花费时间是通过比较子表中的行数和该工具将原始表数据拷贝到新表中的拷贝速率来评估的,如果评估后发现子表中数据能够在少于--chunk-time的时间内alter完成,就会采用该方法。另外,因为在MySQL中alter table比外部拷贝数据的速率快很多,所以拷贝速率是按照--chunk-size-limit来决定的
因为MySQL的限制,外键在改表前后的名字会不一样,改表后新表中的外键名前会加一个下划线,同样,会自动的更改外键相应的索引名字
(3)drop_swap
该方法禁止外键检查(FOREIGN_KEY_CHECKS=0),然后在rename新表之前就将原始表drop掉,这个方法更快而且不会被阻塞,但是风险比较大,风险有二:
在drop掉原始表和rename新表之间有一个时间差,在这段时间里这个表是不存在的,这会导致查询报错
如果rename新表时发生了错误,那问题就大了,因为原始表已经被drop掉了
(4)none
这个方法类似没有“swap”的drop_swap,原始表中的所有外键都会被指定到一个不存在的表上
参数列表
测试用例
添加字段
删除字段
修改字段
字段改名
增加索引
删除索引
参考:https://blog.csdn.net/lovelichao12/article/details/73549939