平时进行修改表的结构,更改字段,新增字段,更改字段名称通常都是经过ALTER TABLE 语法进行修改的。对于小表或者并发访问不是很大的状况是OK。可是若是是在线大表,那就很麻烦。因为表数据量大,复制表须要比较长的时间,在这个时间段里面,表是被加了锁的(写锁),加写锁时其余用户只能select表不能update、insert表。表数据量越大,耗时越长。html
mysql在线ddl(加字段、加索引等修改表结构之类的操做)过程以下:mysql
可见,在这个过程当中会锁表。形成当前操做的表没法写入数据,影响用户使用。因为须要复制原表的数据到中间表,因此表的数据量越大,等待的时候越长,卡死在那里(用户被拒绝执行update和insert操做,表现就是延迟了一直在等待)。sql
对于DDL操做一个基本的想法:它的变化是就地执行仍是执行表拷贝, 在命令结束以后看看显示“rows affected “的值。例如,这里您可能会看到在作不一样类型的DDL操做: 修改列默认值(超级快,不影响表的全部数据): Query OK, 0 rows affected (0.07 sec) 添加索引 (须要时间, 但0 rows affected 代表表没有被复制): Query OK, 0 rows affected (21.42 sec) 改变列的数据类型(须要大量的时间和须要重建表中的全部行): Query OK, 1671168 rows affected (1 min 35.54 sec) 例如, 在一个大表运行一个DDL操做以前,你可能会检查操做是将快仍是慢,以下所示: 克隆表结构。 用少许数据填充克隆的表。 在克隆的表运行DDL操做。 检查 “行受影响”的值是否为零或不是。一个非零值意味着操做须要重建整个表,这可能须要特殊的规划。例如,你可能在计划停机期间作DDL操做,或在复制每一个从服务器。服务器
percona 的 pt-online-schema-change 工具原理:并发
一、若是存在外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,作相应设置的处理。
二、建立一个新的表,表结构为修改后的数据表,用于从源数据表向新表中导入数据。
三、建立触发器,用于记录从拷贝数据开始以后,对源数据表继续进行数据修改的操做记录下来,用于数据拷贝结束后,执行这些操做,保证数据不会丢失。
四、拷贝数据,从源数据表中拷贝数据到新表中。
五、修改外键相关的子表,根据修改后的数据,修改外键关联的子表。
六、rename源数据表为old表,把新表rename为源表名,并将old表删除。
七、删除触发器。工具
可见,复制表的时候无需加锁,不影响原表继续接受写请求;htm