使用 pt-online-schema-change 实现在线DDL

问题背景

平时进行修改表的结构,更改字段,新增字段,更改字段名称一般都是通过ALTER TABLE  语法进行修改的。对于小表或者并发访问不是很大的情况是OK。但是如果是在线大表,那就很麻烦。由于表数据量大,复制表需要比较长的时间,在这个时间段里面,表是被加了锁的(写锁),加写锁时其他用户只能select表不能update、insert表。表数据量越大,耗时越长。

mysql在线ddl(加字段、加索引等修改表结构之类的操作)过程如下:

  1. 对表加锁(表此时只读)
  2. 复制原表物理结构
  3. 修改表的物理结构
  4. 把原表数据导入中间表中,数据同步完后,锁定中间表,并删除原表
  5. rename中间表为原表
  6. 刷新数据字典,并释放锁

可见,在这个过程中会锁表。造成当前操作的表无法写入数据,影响用户使用。由于需要复制原表的数据到中间表,所以表的数据量越大,等待的时候越长,卡死在那里(用户被拒绝执行update和insert操作,表现就是延迟了一直在等待)。

对于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 工具原理:

1、如果存在外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,做相应设置的处理。
2、创建一个新的表,表结构为修改后的数据表,用于从源数据表向新表中导入数据。
3、创建触发器,用于记录从拷贝数据开始之后,对源数据表继续进行数据修改的操作记录下来,用于数据拷贝结束后,执行这些操作,保证数据不会丢失。
4、拷贝数据,从源数据表中拷贝数据到新表中。
5、修改外键相关的子表,根据修改后的数据,修改外键关联的子表。
6、rename源数据表为old表,把新表rename为源表名,并将old表删除。
7、删除触发器。

可见,复制表的时候无需加锁,不影响原表继续接受写请求;

原文地址:https://www.cnblogs.com/chenny7/p/8521837.html

时间: 2024-08-29 15:41:07

使用 pt-online-schema-change 实现在线DDL的相关文章

MySQL在线DDL gh-ost 使用说明

原文:gh-ost: GitHub's online schema migration tool for MySQL http://github.com/github/gh-ost MySQL在线更改schema的工具很多,如Percona的pt-online-schema-change. Facebook的 OSC 和 LHM 等,但这些都是基于触发器(Trigger)的,今天咱们介绍的 gh-ost 号称是不需要触发器(Triggerless)支持的在线更改表结构的工具. 本文先介绍一下当前

MySQL5.7—在线DDL总结

---切记:DDL操作要在业务低峰期进行 1.MySQL各版本,对于DDL的处理方式是不同的,主要有三种: ①:Copy Table方式: 这是InnoDB最早支持的方式.顾名思义,通过临时表拷贝的方式实现的.新建一个带有新结构的临时表,将原表数据全部拷贝到临                    时表,然后Rename,完成创建操作.这个方式过程中,原表是可读的,不可写.但是会消耗一倍的存储空间. ②:Inplace方式:这是原生MySQL 5.5,以及innodb_plugin中提供的方式.

mysql在线ddl操作

mysql5.6开始支持在线ddl,在线ddl能够提供下面的好处: 1提高生产环境的可用性2在ddl执行期间,获得性能和并发性的平衡,可以指定LOCK从句与algorithm从句,lock=exclusize会阻塞整个表的访问,lock=shared会允许查询但不允许dml,lock=none允许查询和dml操作,lock=default或是没有指定,mysql使用最低级别的锁,algorithm指定是拷贝表还是不拷贝表直接内部操作,3只对需要的地方做改变,不是创建一个新的临时表. 之前ddl操

mysql在线DDL(与oracle的区别)

对mysql有所研究的都知道,当mysql某个业务表上有未提交的活动事务的时候,你去执行在线DDL,这相当危险,直接会被卡住,show processlist里面会显示这个DDL遇到了MDL锁等待,即"waiting for table metadata lock",此时如果你去喝咖啡去了...杯具就发生了,因为此时这个业务表连select都会被阻塞. mysql在5.6官方文档里面说自己可以支持大部分在线DDL了,包括常见的加字段.加索引.改字段等等.但是要注意:这里所谓的支持在线D

MySQL5.7 加强了在线DDL(varchar字符集)

在MySQL5.6引入了在线DDL,添加字段和辅助索引不锁表,但修改字段属性是锁表的.请见:http://hcymysql.blog.51cto.com/5223301/1370546 如今在MySQL5.7,加强了修改varchar字段属性不锁表,例: 100万行的表,现在要把pad varchar(65)修改为pad varchar(80),可以看到,不用拷贝数据不锁表. (注:ALGORITHM指定了创建或删除索引的算法,COPY表示按照MySQL 5.1版本之前的方法,即创建临时表.IN

MySQL5.6在线DDL不锁表(在线添加字段)

MySQL5.6在线DDL不锁表(在线添加字段) 解答你也看一下MySQL5.6在线DDL不锁表,现在我有一张1亿的表,需要增加一个字段,假如我让你去增加这个字段,你应该注意什么,具体怎么操作? 操作如下:1.注意磁盘空间(临时表目录)2.当前内存剩余量3.当前有没有大的事务在执行4.innodb_online_alter_log_max_size参数5.然后在从上添加,再在主上添加(不记录binlog),处理完成后再开启 如果直接先在主上操作,那么会导致主从延迟很大(在量比较大的情况下).因为

[资料收集]MySQL在线DDL工具pt-online-schema-change

MySQL在线DDL工具pt-online-schema-change pt-online-schema-change使用说明(未完待续) 官网

MySQL5.6、5.7、8.0在线DDL对比情况

MySQL5.6的版本之后支持了在线DDL,这对于DBA来说是个福音,但是MySQL5.6.5.7和当前的最新版本8.0在各种DDL中的情况不太一样,根据MySQL官方网站的说明整理一份在线DDL的对比情况,具体如下: 原文地址:http://blog.51cto.com/wangwei007/2155574

pt-online-change-ddl(在线ddl)

mysql> desc online_ddl; +---------+--------------+------+-----+-------------------+----------------+ | Field   | Type         | Null | Key | Default           | Extra          | +---------+--------------+------+-----+-------------------+-------------