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 #如果新表中没有的数据,在源表中执行删除就忽略这个操作
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原理解析 博客相关需要阅读的更多相关文章
- 如何在hexo博客中在线阅读pdf
前言 有一些资料或者笔记是pdf版本的,如果想要放在博客中进行阅读,那么就得将其转换为markdown格式或者html格式.但是这样转换后,其原pdf的格式就会混乱了,排版将会变得很困难,不过一山更比 ...
- 关于” 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引” 这篇博客相关的优化采坑记录
之前写过一篇博客是关于记录日志的简单方式的 主要就是 应用->redis->logstash->elasticsearch 整个流程的配置方法和过程的 虽然我们部分线上应用使用 ...
- hexo博客相关
https://www.cnblogs.com/sulishibaobei/p/6428241.html 利用hexo+github+nodejs搭建自我博客的一天 http://www.sulish ...
- pt-online-schema-change原理解析(转)
pt-online-schema-change原理解析 博客相关需要阅读 - zengkefu - 博客园 .pt-online-schema-change工具的使用限制: ).如果修改表有外键,除非 ...
- HTTP协议(转自:小坦克博客)
原文地址:http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html HTTP协议详解 当今web程序的开发技术真是百家争鸣,ASP ...
- Python+爬虫+xlwings发现CSDN个人博客热门文章
☞ ░ 前往老猿Python博文目录 ░ 一.引言 最近几天老猿博客的访问量出现了比较大的增长,从常规的1000-3000之间波动的范围一下子翻了将近一倍,粉丝增长从日均10-40人也增长了差不多一倍 ...
- Django 搭建简易博客
新增一个 APP 博客算是一个功能集,因此我们应将其体现为一个模块.这表现在 Django 应用里则是为其创建一个 APP Package.现在让 manage.py 中的 startapp 闪亮登场 ...
- nodejs环境 + 入门 + 博客搭建
NodeJS:NodeJS是一个使用了Google高性能V8 引擎 的服务器端JavaScript实现.它提供了一个(几乎)完全非阻塞I/O栈,与JavaScript提供的闭包和匿名函数相结合,使之成 ...
- 搭建Hexo博客(三)—换电脑继续写Hexo博客
Hexo和GitHub搭建博客的原理是:Hexo将source下的md文件生成静态的html页面,存放到public目录中,这一步是由命令:hexo -g完成.接下来执行hexo -d命令,就将pub ...
随机推荐
- iOS 7 自定义Back按钮 与 Pop interactive gesture 问题
1.自定义Back按钮 iOS中很多时候我们都会自定义返回按钮,也是一件easy的事,类似如下: // 返回按钮 1 - (void)showNavBackButton { UIButton *bac ...
- LightOJ 1038-Race to 1 Again(概率dp)
题意: 给你一个数n每一步这个数可以变为他的因子,直到这个数变为1,求n变到1的期望步数. 分析: dp[i],表示i变为1的期望步数,dp[1]=0,dp[n]是答案. dp[i]=sum(dp[j ...
- BufferedReader和BufferedWriter读写文件(转载)
http://375940084.blog.51cto.com/2581965/751040 1.创建Student类存储每个学生信息,属性(学号,姓名,出生日期,得分)2.从c:/test/stud ...
- css样式表中的样式覆盖顺序
刚才写zenktodo的时候,通过动态添加class的方式修改一个div的样式,总是不起作用. #navigator { height: 100%; width: 200; position: abs ...
- css优先级判断
概念 浏览器是通过判断优先级,来决定到底哪些属性值是与元素最相关的,从而应用到该元素上.优先级是由选择器组成的匹配规则决定的. 如何计算? 优先级是根据由每种选择器类型构成的级联字串计算而成的. 它不 ...
- C++中的重载,隐藏,覆盖,虚函数,多态浅析
直到今日,才发现自己对重载的认识长时间以来都是错误的.幸亏现在得以纠正,真的是恐怖万分,雷人至极.一直以来,我认为重载可以发生在基类和派生类之间,例如: class A { public: void ...
- 【转】MySql数据库--mysql_real_escape_string()函数
MySql数据库--mysql_real_escape_string()函数 unsigned long mysql_real_escape_string(MYSQL *mysql, char *to ...
- Visual Studio 2013智能提示失效解决办法
各种解决VS2013智能提示失效办法: 1.重置所有设置 工具->导入导出设置->重置所有设置 2.智能提示开关: 工具->选项->文本编辑器->C#->常规 ...
- google_protobuf数据类型
要通信,必须有协议,否则双方无法理解对方的码流.在protobuf中,协议是由一系列的消息组成的.因此最重要的就是定义通信时使用到的消息格式. Protobuf消息定义 消息由至少一个字段组合而成,类 ...
- 嵌入式LINUX入门到实践(二)
这篇中将围绕韦东山LINUX第二部分教程源码,对IIC协议进行程序实现上的分析. /* I2C registers */#define IICCON (*(volatile unsigned ...