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 ...
随机推荐
- C语言数组指针
C语言中的数组指针与指针数组: ·数组指针一.区分 首先我们需要了解什么是数组指针以及什么是指针数组,如下: int *p[5];int (*p)[5];数组指针的意思即为通过指针引用数组,p先和*结 ...
- Flask 框架
装饰器知识回顾 http://www.cnblogs.com/0bug/p/7978595.html 普通装饰器格式: def wrapper(func): def inner(*args, **kw ...
- sql server 2016 附加 其它目录的数据库
如果数据库不在默认目录,那么需要将 mdf所在目录或者 mdf文件 添加 用户 [NT SERVICE\MSSQLSERVER]的创建权限,否则会提示没有权限, 具体详见: https://docs. ...
- nginx http转 https
场景 项目前期使用http,后期为了安全方面的考虑,启用了https.项目架构:前端使用nginx作为多个tomcat实例的反向代理和负载均衡.实际上只需要在nginx上启用https即可,使客户端与 ...
- 性能测试day03_前端分析调优思路
刚刚看到有人支持我写的博客,表示还是比较感动的,发现热心的用户在我的博客留言说“一个系统每天有200万在线用户,问我怎么设计性能场景?”,其实这个问题呢就属于业务没理清,这个问题就像我问你,一个城市一 ...
- 201. Spring Boot JNDI:Spring Boot中怎么玩JNDI
[视频&交流平台] àSpringBoot视频:http://t.cn/R3QepWG à SpringCloud视频:http://t.cn/R3QeRZc à Spring Boot源 ...
- E0264 Unable to execute '"/usr/bin/codesign" ...'
E0264 Unable to execute '"/usr/bin/codesign" ...' http://docwiki.embarcadero.com/RADStudio ...
- 深度学习原理与框架-递归神经网络-RNN网络基本框架(代码?) 1.rnn.LSTMCell(生成单层LSTM) 2.rnn.DropoutWrapper(对rnn进行dropout操作) 3.tf.contrib.rnn.MultiRNNCell(堆叠多层LSTM) 4.mlstm_cell.zero_state(state初始化) 5.mlstm_cell(进行LSTM求解)
问题:LSTM的输出值output和state是否是一样的 1. rnn.LSTMCell(num_hidden, reuse=tf.get_variable_scope().reuse) # 构建 ...
- 【Noip模拟 20161005】运货
问题描述 小ww开了一家快递公司,在nn个城市之间进行货物运输工作,一共雇了mm个快递员. 每个快递员性格很奇特,第ii号快递员只愿意将货物从城市sisi运送到titi(甚至不愿意将货物 从titi运 ...
- python中类与对象之继承
面对对象的三大特性之继承 1.什么是继承? 在程序中,继承指的是class与class之间的关系 继承是一种关系,必须存在两个class才能产生这种关系:被继承的class称为父类,继承的class称 ...