都说pt-toolkit工具集中的pt-online-schema-change可以在线不锁表修改表结构,那么这个工具具体是什么原理呢,请见下面娓娓道来:

1.pt-online-schema-change工具的使用限制:

1)、如果修改表有外键,除非使用 --alter-foreign-keys-method 指定特定的值,否则工具不予执行

2)、被修改表必须要有主键,否则报错:Cannot chunk the original table `houyi`.`ga`: There is no good index and the table is oversized. at ./pt-online-schema-change line 5353.

3)、被修改表上不能有针对after delete|insert|update三个触发器,否则修改表结构操作失败

2.创建执行环境

安装这里就不说了,直接到这里下载安装:

源码:https://www.percona.com/downloads/percona-toolkit/2.2.17/tarball/percona-toolkit-2.2.17.tar.gz

RPM:https://www.percona.com/downloads/percona-toolkit/2.2.17/RPM/percona-toolkit-2.2.17-1.noarch.rpm

创建测试数据:

mysql> create database xiaoboluo;

Query OK, 0 rows affected (0.04 sec)

mysql> create table teset_ptosc(id int unsigned not null primary key auto_increment,test varchar(100));

Query OK, 0 rows affected (0.04 sec)

mysql> insert into teset_ptosc(test) values('test1'),('test2'),('test3');

Query OK, 3 rows affected (0.16 sec)

Records: 3  Duplicates: 0  Warnings: 0

mysql> set global general_log=1;

Query OK, 0 rows affected (0.02 sec)

3.执行pt-online-schema-change命令添加一个字段test2:

shell > pt-online-schema-change --alter 'add column test2 varchar(100)' p='password',u=root,D=xiaoboluo,t=teset_ptosc --no-check-replication-filters --execute

执行输出过程如下:

Found 1 slaves:

localhost.localdomain

Will check slave lag on:

localhost.localdomain

Operation, tries, wait:

copy_rows, 10, 0.25

create_triggers, 10, 1

drop_triggers, 10, 1

swap_tables, 10, 1

update_foreign_keys, 10, 1

Altering `xiaoboluo`.`teset_ptosc`...

Creating new table...

Created new table xiaoboluo._teset_ptosc_new OK.

Altering new table...

Altered `xiaoboluo`.`_teset_ptosc_new` OK.

2016-03-14T00:55:56 Creating triggers...

2016-03-14T00:55:56 Created triggers OK.

2016-03-14T00:55:56 Copying approximately 1 rows...

2016-03-14T00:55:56 Copied rows OK.

2016-03-14T00:55:56 Swapping tables...

2016-03-14T00:55:56 Swapped original and new tables OK.

2016-03-14T00:55:56 Dropping old table...

2016-03-14T00:55:56 Dropped old table `xiaoboluo`.`_teset_ptosc_old` OK.

2016-03-14T00:55:56 Dropping triggers...

2016-03-14T00:55:56 Dropped triggers OK.

Successfully altered `xiaoboluo`.`teset_ptosc`.

从上面的执行输出中就可以大概看到执行过程:

创建一个新表,然后alter新表,然后创建触发器,然后copy数据,然后交换表,然后删除old表,然后删除触发器,最后返回成功alter的提示,那么,具体在数据库中是如何操作的呢,前面打开了general_log,现在去查看下general_log文件中的内容:

4.结合general_log文件中的输出,pt-online-schema-change的大致过程如下:

1)、首先使用帐号密码连接到mysql后,获取指定表的状态信息,检查是否有触发器,检查表是否有主键。

2)、接着按照修改表的表定义,新建一个名为'_tb_new'不可见的临时表,对这个表执行alter添加字段,并校验是否执行成功。

3)、然后针对源表创建三个触发器,分别如下:

create trigger db_tb_del after delete on db.tb for each row delete ignore from db._tb_new where db._tb_new.id <=> OLD.id #删掉新表中db._tb_new.id <=> OLD.id的数据,否则忽略操作

create trigger db_tb_del after update on db.tb for each row replace into db._tb_new(id,...) values(new.id,...)  #源表执行update的时候,把对应的数据replace into的方式写入新表

create trigger db_tb_del after insert on db.tb for each row replace into db._tb_new(id,...) values(new.id,...)  #源表执行iinsert操作的时候,把对应的数据replace into的方式写入新表

4)、触发器创建好之后会执行insert low_priority ignore into db._tb_new(id,..) select id,... from tb lock in share mode语句复制源表数据到新表。

5)、复制完成之后执行语句:rename table db.tb to db._tb_old,db._tb_new to db.tb同时把源表修改为_tb_old格式,把新表_tb_new修改为源表名字的原子修改。

6)、接着,如果没有加不删除old表的选项,那么就会删除Old表,然后删除三个触发器。到这里就完成了在线表结构的修改 。整个过程只在rename表的时间会锁一下表,其他时候不锁表。

5.下面是general_log输出原文的相关部分:

642 Query    SHOW TABLES FROM `xiaoboluo` LIKE 'teset\_ptosc'

642 Query    SHOW TRIGGERS FROM `xiaoboluo` LIKE 'teset\_ptosc'

642 Query    /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

642 Query    USE `xiaoboluo`

642 Query    SHOW CREATE TABLE `xiaoboluo`.`teset_ptosc`

642 Query    /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */

642 Query    EXPLAIN SELECT * FROM `xiaoboluo`.`teset_ptosc` WHERE 1=1

642 Query    SELECT table_schema, table_name FROM information_schema.key_column_usage WHERE referenced_table_schema='xiaoboluo' AND referenced_table_name='teset_ptosc'

642 Query    SHOW VARIABLES LIKE 'wsrep_on'

642 Query    /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

642 Query    USE `xiaoboluo`

642 Query    SHOW CREATE TABLE `xiaoboluo`.`teset_ptosc`

642 Query    /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */

642 Query    CREATE TABLE `xiaoboluo`.`_teset_ptosc_new` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`test` varchar(100) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

642 Query    ALTER TABLE `xiaoboluo`.`_teset_ptosc_new` add column test2 varchar(100)

642 Query    /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

642 Query    USE `xiaoboluo`

642 Query    SHOW CREATE TABLE `xiaoboluo`.`_teset_ptosc_new`

642 Query    /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */

642 Query    CREATE TRIGGER `pt_osc_xiaoboluo_teset_ptosc_del` AFTER DELETE ON `xiaoboluo`.`teset_ptosc` FOR EACH ROW DELETE IGNORE FROM `xiaoboluo`.`_teset_ptosc_new` WHERE `xiaoboluo`.`_teset_ptosc_new`.`id` <=> OLD.`id`

642 Query    CREATE TRIGGER `pt_osc_xiaoboluo_teset_ptosc_upd` AFTER UPDATE ON `xiaoboluo`.`teset_ptosc` FOR EACH ROW REPLACE INTO `xiaoboluo`.`_teset_ptosc_new` (`id`, `test`) VALUES (NEW.`id`, NEW.`test`)

642 Query    CREATE TRIGGER `pt_osc_xiaoboluo_teset_ptosc_ins` AFTER INSERT ON `xiaoboluo`.`teset_ptosc` FOR EACH ROW REPLACE INTO `xiaoboluo`.`_teset_ptosc_new` (`id`, `test`) VALUES (NEW.`id`, NEW.`test`)

642 Query    EXPLAIN SELECT * FROM `xiaoboluo`.`teset_ptosc` WHERE 1=1

642 Query    EXPLAIN SELECT `id`, `test` FROM `xiaoboluo`.`teset_ptosc` LOCK IN SHARE MODE /*explain pt-online-schema-change 45383 copy table*/

642 Query    INSERT LOW_PRIORITY IGNORE INTO `xiaoboluo`.`_teset_ptosc_new` (`id`, `test`) SELECT `id`, `test` FROM `xiaoboluo`.`teset_ptosc` LOCK IN SHARE MODE /*pt-online-schema-change 45383 copy table*/

642 Query    SHOW WARNINGS

642 Query    SHOW GLOBAL STATUS LIKE 'Threads_running'

642 Query    RENAME TABLE `xiaoboluo`.`teset_ptosc` TO `xiaoboluo`.`_teset_ptosc_old`, `xiaoboluo`.`_teset_ptosc_new` TO `xiaoboluo`.`teset_ptosc`

642 Query    DROP TABLE IF EXISTS `xiaoboluo`.`_teset_ptosc_old`

642 Query    DROP TRIGGER IF EXISTS `xiaoboluo`.`pt_osc_xiaoboluo_teset_ptosc_del`

642 Query    DROP TRIGGER IF EXISTS `xiaoboluo`.`pt_osc_xiaoboluo_teset_ptosc_upd`

642 Query    DROP TRIGGER IF EXISTS `xiaoboluo`.`pt_osc_xiaoboluo_teset_ptosc_ins`

642 Query    SHOW TABLES FROM `xiaoboluo` LIKE '\_teset\_ptosc\_new'

pt-online-schema-change原理解析的更多相关文章

  1. 【算法】(查找你附近的人) GeoHash核心原理解析及代码实现

    本文地址 原文地址 分享提纲: 0. 引子 1. 感性认识GeoHash 2. GeoHash算法的步骤 3. GeoHash Base32编码长度与精度 4. GeoHash算法 5. 使用注意点( ...

  2. Spring IOC设计原理解析:本文乃学习整理参考而来

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  3. pt-online-schema-change原理解析(转)

    pt-online-schema-change原理解析 博客相关需要阅读 - zengkefu - 博客园 .pt-online-schema-change工具的使用限制: ).如果修改表有外键,除非 ...

  4. android黑科技系列——微信抢红包插件原理解析和开发实现

    一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  5. android黑科技系列——Apk的加固(加壳)原理解析和实现

    一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...

  6. 5、Spring Boot 2.x 启动原理解析

    1.5 Spring Boot 启动原理解析 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏 ...

  7. Android中微信抢红包插件原理解析和开发实现

    一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  8. 6_1.springboot2.x整合JDBC与数据源配置原理解析

    1.引言 对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合 Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置.引入各种xxxTemplate,x ...

  9. EntityFramework Core表名原理解析,让我来,揭开你神秘的面纱

    前言 上一节我们针对最开始抛出的异常只是进行了浅尝辄止的解析,是不是有点意犹未尽的感觉,是的,我也有这种感觉,看到这里相信您和我会有一些疑惑,要是我们接下来通过注解.Fluent APi.DbSet分 ...

  10. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

随机推荐

  1. asp.net mvc 过滤器

    https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#ordering 1. 对于应用在 Action 上的多个行为 ...

  2. 有关windows系统的EXE和DLL文件说法错误

    正确答案: B C   你的答案: C (错误) EXE和DLL文件都是PE文件 EXE不能有导出函数,DLL可以有导出函数 EXE有x86和x64之分,则DLL没有 EXE可以单独运行,DLL则不行 ...

  3. C++ 小工具一键解决SVN Clean Up 失败的问题

    参考文章: 1.http://blog.csdn.net/luochao_tj/article/details/46358145 2.http://blog.csdn.net/segen_jaa/ar ...

  4. status bar、navigationBar、tableView吸顶view设置

    1. 隐藏navigationBar self.navigationController.navigationBar.hidden = YES; 2. status bar设置 -(void)view ...

  5. Scipy - Python library - Math tool - Begin

    Introduction Scientific Computing Tools for Python. Seen in Scipy.org. Environment Linux, CentOS 7 w ...

  6. Java web学习filter (1)

    一.概念:Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源: 例如Jsp, Servlet, 静态图片文件 ...

  7. Windows Live Writer体验

    [安装] 首先下载安装包安装软件,没啥好说的,baidupan有记录: 顺便下载两个工具,备用: a)SourceCodePlugin_version_1.1.zip 将WindowsLiveWrit ...

  8. 网站性能,javascript性能相关知识点

    一.高性能网站 <高性能网站建设指南>一书中提出用户只有10%-20%最终用户响应时间是花在从web服务器获取html文档并传送到浏览器中,80%的时间都花在了等待页面组件中,由此提出了构 ...

  9. Could not find class 'android.support.v4.view.ViewPager', referenced from me

    http://www.ithao123.cn/content-8236579.html 按照上面链接说的来做,弄完Clean一下项目,就可以运行.

  10. lkx开发日志2-第一次团队讨论

    遇到的问题 冰球与击球手碰撞的形式有两种.第一种:击球手的速度不指向冰球圆心,这样碰撞后冰球会旋转.第二种:击球手的速度指向冰球圆心,直接科运用动量定理计算两者速度的变化.考虑到时间限制,团队假设冰球 ...