17. pt-online-schema-change
在平时MySQL的运维过程中,经常会遇到表结构的变更。在表比较小的时候,直接进行变更,时间较短,但是当表非常大的时候,这么做会导致应用卡死,服务不可用。
目前InnoDB引擎是通过以下步骤来进行DDL的:
1 利用DDL之后的语句创建一张临时表
2 在原表上加write lock,阻塞所有DML操作
3 将原表数据复制到临时表
4 将临时表和原表重命名,然后drop原始表
5 释放 write lock。
在这个DDL过程中,针对大表进行的write lock将持续非常长的时间,我们可以用为此 perconal 推出一个工具 pt-online-schema-change,在进行DDL的时候不堵塞原表的读写。
工作原理:
如果表有外键,除非使用 --alter-foreign-keys-method 指定特定的值,否则工具不予执行。
1 创建一张和原表一样的空表结构。
2 执行空表的DDL
3 在原表上创建触发器,将对原表的修改操作记录下来。
4 复制数据到新的空表中,复制完成后,应用修改记录。
注意:如果表中已经定义了触发器这个工具就不能工作了。
5 复制完成后在重命名原表和新的表
============================================
create table t02(id int);
pt-online-schema-change --alter="add name varchar(50) not null default ''" \
h=192.168.100.101,P=3306,u=admin,p=admin,D=db01,t=t02 \
--dry-run --print \
--execute
pt-online-schema-change --alter="modify id int unsigned not null auto_increment primary key" \
h=192.168.100.101,P=3306,u=admin,p=admin,D=db01,t=t02 \
--dry-run --print \
--execute
pt-online-schema-change --alter="add index idx_name_score(name,score)" \
h=192.168.100.101,P=3306,u=admin,p=admin,D=db01,t=t02 \
--dry-run --print \
--execute
pt-online-schema-change --alter="drop index idx_finger" \
h=192.168.100.101,P=3306,u=admin,p=admin,D=db01,t=t02 \
--dry-run --print \
--execute
pt-online-schema-change --alter="engine=innodb" \
h=192.168.100.101,P=3306,u=admin,p=admin,D=db01,t=t02 \
--dry-run --print \
--execute
================================================
【DSN】
指定时注意大小写敏感,“=”左右不能有空格,多个值之间用逗号分隔
1. A charset
2. D database
3. F mysql_read_default_file
4. h host
5. p password
6. P port
7. S mysql_socket
8. t table
9. u user
【具体执行进程解析】
现在执行一个改表语句并开启general log 观察一下
1
pt-online-schema-change --alter 'add column c1 int' u=username,S=/data/mysql.sock,D=test,t=a --execute
1. 首先就是各种show,各种set,有兴趣自己去看看,主要就是对权限的检查,超时时间的设定,当前系统的繁忙程度;
然后就是对表的检查,如是否有触发器的存在,以及如下查询:
explain SELECT * FROM `test`.`a` WHERE 1=1;
SELECT table_schema, table_name FROM information_schema.key_column_usage
WHERE referenced_table_schema='test' AND referenced_table_name='a';
SHOW CREATE TABLE `test`.`a`;
到这里表的情况检查完毕
2. 现在就开始建新表,注意名字的改变,a变成了_a_new
并在这个空表上直接alter
ALTER TABLE `test`.`_a_new` add column c1 int
然后做一下检查看alter是否成功
SHOW CREATE TABLE `test`.`_a_new`
3. 建立触发器
CREATE TRIGGER `pt_osc_test_a_del` AFTER DELETE ON `test`.`a` FOR EACH ROW DELETE IGNORE
FROM `test`.`_a_new` WHERE `test`.`_a_new`.`id` <=> OLD.`id`
CREATE TRIGGER `pt_osc_test_a_upd` AFTER UPDATE ON `test`.`a` FOR EACH ROW
REPLACE INTO `test`.`_a_new` (`id`, `name`, `type`, `b`) VALUES (NEW.`id`, <br>NEW.`name`, NEW.`type`, NEW.`b`)
CREATE TRIGGER `pt_osc_test_a_ins` AFTER INSERT ON `test`.`a` FOR EACH ROW
REPLACE INTO `test`.`_a_new` (`id`, `name`, `type`, `b`) VALUES (NEW.`id`, <br>NEW.`name`, NEW.`type`, NEW.`b`)
4. 通过explain来判断执行chunk拷贝的成本,第一个chunk的大小固定为1000行,后面的chunk根据自己的指定,如chunk-time来确定大小
EXPLAIN SELECT `id`, `name`, `type`, `b` FROM `test`.`a` FORCE INDEX(`PRIMARY`)
WHERE ((`id` >= '1')) AND ((`id` <= '1000')) LOCK IN SHARE MODE
确定不会影响系统正常运行后,执行insert操作,将原始表中的数据按照当前chunk大小拷贝到新表中
INSERT LOW_PRIORITY IGNORE INTO `test`.`_a_new` (`id`, `name`, `type`, `b`)
SELECT `id`, `name`, `type`, `b` FROM `test`.`a` FORCE INDEX(`PRIMARY`)
WHERE ((`id` >= '1')) AND ((`id` <= '1000')) LOCK IN SHARE MODE
5. 一个chunk拷贝结束后立即对系统负载进行检查
SHOW GLOBAL STATUS LIKE 'Threads_running'
没问题的话就继续explain,insert,负载太高的话就暂停拷贝等待负载降低,以此类推,直到所有拷贝结束
6. 拷贝结束后,对新表状态是否进行检查
ANALYZE TABLE `test`.`_a_new`
如果正常OK就往下走,如果不OK就删掉新表或不删报错退出(根据参数指定),默认是删掉
7. 确定新表没有问题后就用新表来代替旧表,注意旧表的名字在这个时候也会改一下
RENAME TABLE `test`.`a` TO `test`.`_a_old`, `test`.`_a_new` TO `test`.`a`
8. 替换成功后默认是将旧表删掉
DROP TABLE IF EXISTS `test`.`_a_old`
9. 将之前建的触发器删掉
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_a_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_a_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_a_ins`
10. 最后再确定一下新表是否改名成功
SHOW TABLES FROM `test` LIKE '\_a\_new'
SHOW TABLES FROM `test` LIKE 'a'
改表完成!!!
17. pt-online-schema-change的更多相关文章
- AppBoxFuture(四). 随需而变-Online Schema Change
需求变更是信息化过程中的家常便饭,而在变更过程中如何尽可能小的影响在线业务是比较头疼的事情.举个车联网监控的例子:原终端设备上传车辆的经纬度数据,新的终端设备支持同时上传速度数据,而旧的车辆状态表 ...
- schema change + ogg 变更手册
Check OGG until no data queuing in replication process:testRO:a)login test5 –l oggmgrb)oggc)#ggsci ...
- Online Schema Change for MySQL
It is great to be able to build small utilities on top of an excellent RDBMS. Thank you MySQL. This ...
- 3.Appium运行时出现:Original error: Android devices must be of API level 17 or higher. Please change your device to Selendroid or upgrade Android on your device
参考博客:https://blog.csdn.net/niubitianping/article/details/52624417 1.错误信息:Original error: Android dev ...
- Online, Asynchronous Schema Change in F1
F1: A Distributed SQL Database That Scales http://disksing.com/understanding-f1-schema-change ma ...
- Schema 与数据类型优化
这是<高性能 MySQL(第三版)>第四章<Schema 与数据类型优化>的读书笔记. 1. 选择优化的数据类型 数据类型的选择原则: 越小越好:选择满足需求的最小类型.注意, ...
- Online Schema Upgrade in MySQL Galera Cluster using TOI Method
http://severalnines.com/blog/online-schema-upgrade-mysql-galera-cluster-using-toi-method As a fo ...
- MySQL--performance schema学习
启用performance schema 在MySQL 5.6.6版本后,performance schema被默认打开 通常MySQL的二进制版本都默认支持PS, 如果使用编译源码安装,在cmake ...
- SQLite剖析之存储模型
前言 SQLite作为嵌入式数据库,通常针对的应用的数据量相对于DBMS的数据量小.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树的形式来组织这 ...
- System Error Codes
很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...
随机推荐
- 将string转为同名类名,方法名。(c#反射)
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace stri ...
- SpringBoot项目单元测试
关于SpringBoot的单元测试,描述一下三种单元测试的方式. 1.约定 单元测试代码写在src/test/java目录下单元测试类命名为*Test,前缀为要测试的类名 2. 使用mock方式单元测 ...
- Container 、Injection
Container: Linux容器作为一类操作系统层面的虚拟化技术成果,旨在立足于单一Linux主机交付多套隔离性Linux环境.与虚拟机不同,容器系统并不需要运行特定的访客操作系统.相反,容器共享 ...
- firefox修改语言
下面咱们就可以开始更改设置来让咱们安装好的语言成为默认的语言. 首先在空窗口里输入以下地址:about:config,进入设置页面. 2 请大家定位到general.useragent.locale这 ...
- 未预期的符号 `$'{\r'' 附近有语法错误
../runcmake: 行 2: $'\r': 未找到命令 ../runcmake: 行 3: 未预期的符号 `$'{\r'' 附近有语法错误 考虑到代码是从windows下一直过来的,脚本可能在格 ...
- linux服务之apache篇(一)
1.apache介绍:使用率最高的网站服务器: URL:统一资源定位符: 端口:http:80 https:443 2.apache三种工作模式: prefork:一个线程处理一个请求(占用内存多 ...
- 微信小程序 实现三级联动-省市区
github项目地址 https://github.com/z1511676208/chooseAddr 序:项目中需要用到三级联动,自己试着写了下,也查了一些资料,现在把这个记录一下,里面地区数 ...
- 子页面调整父亲页面的iframe元素
$('iframe', parent.document).attr('scrolling','no');
- 《从零玩转python+人工智能-3》120,122节课深度优先疑问解答
深度优先(从左往右): 按照这个原则来:至于使用栈,或者队列:根据它们不同的特性:最终务必保证最终结果是原继承结构的“从左往右”:所以,如果是栈,就是右侧先入栈,左侧再入(这样左侧能先出来,遵循从左 ...
- js day03
一)jQuery常用AJAX-API 目的:简化客户端与服务端进行局部刷新的异步通讯 (1)取得服务端当前时间 简单形式:jQuery对象.load(url) 返回结果自动添加到jQuery对象代表的 ...