pt-online-schema-change原理解析
都说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原理解析的更多相关文章
- 【算法】(查找你附近的人) GeoHash核心原理解析及代码实现
本文地址 原文地址 分享提纲: 0. 引子 1. 感性认识GeoHash 2. GeoHash算法的步骤 3. GeoHash Base32编码长度与精度 4. GeoHash算法 5. 使用注意点( ...
- Spring IOC设计原理解析:本文乃学习整理参考而来
Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...
- pt-online-schema-change原理解析(转)
pt-online-schema-change原理解析 博客相关需要阅读 - zengkefu - 博客园 .pt-online-schema-change工具的使用限制: ).如果修改表有外键,除非 ...
- android黑科技系列——微信抢红包插件原理解析和开发实现
一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...
- android黑科技系列——Apk的加固(加壳)原理解析和实现
一.前言 今天又到周末了,憋了好久又要出博客了,今天来介绍一下Android中的如何对Apk进行加固的原理.现阶段.我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk, ...
- 5、Spring Boot 2.x 启动原理解析
1.5 Spring Boot 启动原理解析 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏 ...
- Android中微信抢红包插件原理解析和开发实现
一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...
- 6_1.springboot2.x整合JDBC与数据源配置原理解析
1.引言 对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合 Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置.引入各种xxxTemplate,x ...
- EntityFramework Core表名原理解析,让我来,揭开你神秘的面纱
前言 上一节我们针对最开始抛出的异常只是进行了浅尝辄止的解析,是不是有点意犹未尽的感觉,是的,我也有这种感觉,看到这里相信您和我会有一些疑惑,要是我们接下来通过注解.Fluent APi.DbSet分 ...
- [原][Docker]特性与原理解析
Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...
随机推荐
- JavaScript + PHP 实现刷新继续保持倒计时的按钮
场景:发送一个验证码到手机,当验证码发出时,会提示隔 1 分钟之后可以再次发送.通常有这几种方式防止恶意请求,一是再次发送之前需要输入验证码,二是在指定的时间间隔之内不能再次发送. 有些网站在 1 分 ...
- 几何服务,cut功能,输入要素target(修改前)内容。
几何服务,cut功能测试,输入要素target(修改前)内容. {"geometryType":"esriGeometryPolyline","geo ...
- (。・・)ノ~个人java学习随笔记录
基本认识 1.编程思维 根据这几天的java学习,编写程序最重要的就是要有一个清晰的思路.语法上的错误可以跟随着不断的联系与学习来弥补,清晰的思维却只有自己来前期模仿,后面慢慢摸索形成一套属于自己的思 ...
- WordPress基础:文章的自定义栏目的使用
写文章只有标题和内容,那么我想加个加个怎么办呢?这时候就可以用到自定义栏目了,这个功能相当于增加了一个键值对 1.启动“自定义栏目” 2.定义键值对 3.调用自定义栏目值 <?php $pric ...
- phpexcel 导出 科学计数问题
今天在用php做excel导出的时候遇到了一个小问题,如图 单元格默认格式为常规格式,当数值过长时就会变成科学计数. 解决方法: 如果输出的excel的$data数据是手动添加的,那就在对应值得后面添 ...
- div垂直居中
width:265px; height:130px; display:table-cell; vertical-align:middle; text-align:center;
- Swift 2.x -> Swift 3.0
Swift 3.0 相对于 2.x 有很大变化.特别是因为命名习惯的改变,导致许多 Api 都发生了变化.总的趋势是让表示更简洁. 对旧的代码升级,大部分可以根据提示来进行更正.但也有的需要手动修改. ...
- AOP programming paradiag
AOP https://en.wikipedia.org/wiki/Aspect-oriented_programming Typically, an aspect is scattered or t ...
- Java 中 ThreadLocal 内存泄露的实例分析
前言 之前写了一篇深入分析 ThreadLocal 内存泄漏问题是从理论上分析ThreadLocal的内存泄漏问题,这一篇文章我们来分析一下实际的内存泄漏案例.分析问题的过程比结果更重要,理论结合实际 ...
- 前端安全配置之Content-Security-Policy(csp)
什么是CSP CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源( ...