标签:pt-online-schema-change pt-toolkit
pt-online-schema-change
不锁表的情况下,修改表结构.
该工具执行的基本流程如下:
判断各种参数
如果表有外键,除非使用 --alter-foreign-keys-method 指定特定的值,否则工具不予执行。
根据原表"t",创建一个名称为"_t_new"的新表
执行ALTER TABLE语句修改新表"_t_new"
创建3个触发器,名称格式为pt_osc_库名_表名_操作类型,比如
CREATE TRIGGER `pt_osc_dba_t_del` AFTER DELETE ON `dba`.`t` FOR EACH ROW DELETE IGNORE FROM `dba`.`_t_new` WHERE `dba`.`_t_new`.`id` <=> OLD.`id`
CREATE TRIGGER `pt_osc_dba_t_upd` AFTER UPDATE ON `dba`.`t` FOR EACH ROW REPLACE INTO `dba`.`_t_new` (`id`, `a`, `b`, `c1`) VALUES (NEW.`id`, NEW.`a`, NEW.`b`, NEW.`c1`)
CREATE TRIGGER `pt_osc_dba_t_ins` AFTER INSERT ON `dba`.`t` FOR EACH ROW REPLACE INTO `dba`.`_t_new` (`id`, `a`, `b`, `c1`) VALUES (NEW.`id`, NEW.`a`, NEW.`b`, NEW.`c1`)
开始复制数据,比如
INSERT LOW_PRIORITY IGNORE INTO `dba`.`_t_new` (`id`, `a`, `b`, `c1`) SELECT `id`, `a`, `b`, `c1` FROM `dba`.`t` LOCK IN SHARE MODE /*pt-online-schema-change 28014 copy table*/
复制完成后,交互原表和新表,执行RENAME命令,如 RENAME TABLE t to _t_old, _t_new to t;
删除老表,_t_old
删除触发器
修改完成
OPTIONS
参数 --dry-run 和 --execute 是互斥的.
该工具接收额外的命名行参数.更多信息请参考”SYNOPSIS"和usage部分.
--alter
type: string
结构修改,不带ALTER TABLE关键字.你可以执行多个表的修改操作,在它们之间用逗号分割.关于ALTER TABLE语法,请参考MySQL手册.
该参数有以下局限性,如果被触发,会导致这个工具执行失败:
不能指定rename语句.
不能用删除列添加新列的方法重命名.该工具将不能复制原表中此列的数据到新列.
如果你添加一个没有默认值新列并且属性设置为NOT NULL,该工具将不能执行,它不会给你指定一个默认值.
删除外键约束,需要指定一个外键的名字,但是,这个名字并不是外键的名字,而是一个区别于外键的名字.这是MySQL的限制.在创建新表的时候, pt-online-schema-change会创建一个以下划线开头的外键.比如
CONSTRAINT `fk_foo` FOREIGN KEY (`foo_id`) REFERENCES `bar` (`foo_id`)
然后,必须这样指定
--alter "DROP FOREIGN KEY _fk_foo"
在MySQL 5.0版本操作可能会有问题.
--alter-foreign-keys-method
如何把外键引用到新表?需要特殊处理带有外键约束的表,以保证它们可以应用到新表.当重命名表的时候,外键关系会带到重命名后的表上.
该工具有两种方法,可以自动找到子表,并修改约束关系.
auto, 在rebuild_constraints和drop_swap两种处理方式中选择一个.
rebuild_constraints, 使用 ALTER TABLE语句先删除外键约束,然后再添加.如果子表很大的话,会导致长时间的阻塞.
drop_swap, 执行FOREIGN_KEY_CHECKS=0,禁止外键约束,删除原表,再重命名新表.
这种方式很快,也不会产生阻塞,但是有风险:
1, 在删除原表和重命名新表的短时间内,表是不存在的,程序会返回错误.
2, 如果重命名表出现错误,也不能回滚了.因为原表已经被删除.
none, 类似"drop_swap"的处理方式,但是它不删除原表,并且外键关系会随着重命名转到老表上面.使用SHOW ENGINE INNODB STATUS;命令会发现如下错误信息
Trying to add to index `idx_fk_staff_id` tuple:
DATA TUPLE: 2 fields;
0: len 1; hex 05; asc ;;
1: len 4; hex 80000001; asc ;;
But the parent table `sakila`.`staff_old`
or its .ibd file does not currently exist!
--ask-pass
连接MySQL时,提示输入密码
--charset
设置字符集,相当于用客户端执行"SET NAMES UTF8"命令
--[no]check-alter
解析并检查alter指定的命令:
在以前的版本,使用CHANGE COLUMN命令会导致数据丢失,现在的版本虽然改进,但是在执行前,还应该使用 --dry-run 和 --print 查看一下详细的操作情况.
DROP PRIMARY KEY, 执行该命令的话,会发出警告.
--check-interval
检查间隔,默认是1秒.请看--max-lag参数.
--[no]check-plan
为了安全,检查查询的执行计划.默认情况下,这个工具在执行查询之前会先EXPLAIN,以获取一次少量的数据,如果是不好的EXPLAIN,那么会获取一次大量的数据.
这个工具会多次执行EXPALIN,如果EXPLAIN不同的结果,那么就会认为这个查询是不安全的.
--[no]check-replication-filters
检查MySQL的复制过滤器,如果存在就报错退出.
如:binlog_ignore_db 和 replicate_do_db
--check-slave-lag
指定一个从库的DSN连接地址,如果从库超过--max-lag参数设置的值,就会暂停操作.
--chunk-index
为chunk指定一个索引(使用FORCE INDEX语法).
默认情况下,工具会自动选择一个合适的索引.如果指定的索引不存在,该工具会自动选择一个合适的.
--chunk-index-columns
选择使用具有n列的索引,多用于复合索引.
--chunk-size
指定块的大小,默认是1000行,可以添加k,M,G后缀.这个块的大小要尽量与--chunk-time匹配.
如果明确指定这个选项,那么每个块就会指定行数的大小.
--chunk-size-limit
当需要复制的块远大于设置的chunk-size大小,就不复制.默认值是4.0
一个没有主键或唯一索引的表,块大小就是不确定的.
--chunk-time
在chunk-time执行的时间内,动态调整chunk-size的大小,以适应服务器性能的变化.
该参数设置为0,或者指定chunk-size,都可以禁止动态调整.
--config
执行配置文件,必须在命令行的第一个参数位置.
--critical-load
测试例子:
1)添加一列,并不真正执行
pt-online-schema-change –alter “add column c1 int” D=mydb,t=mytable –dry-run
2)更新存储引擎为InnoDB,不删除原表
pt-online-schema-change –alter “ENGINE=InnoDB” –no-drop-old-table –print –statistics –execute D=mydb,t=mytable –execute
通过OSC实现slave和master数据差异时候的恢复.有人说,这个是pt-table-sync该干的事情.但是在表数据差异较大的时候,使用OSC可能效率更好,而且更加简单可靠.
OSC如何实现master到slave的数据差异恢复的?
由于OSC的原理是新建表和使用触发器.然后把原表的数据insert into select
from的方式导入新表.如果这个时候,我们把binlog改成row格式.那么insert
into记录的肯定是源表的数据了.触发器在row格式的时候,也是在日志中记录的源表数据.也就是说,通过OSC可以逻辑的,无阻塞的把源表的数据同步
到所有slave.
pt-online-schema-change –set-vars ‘binlog_format=ROW’ –alter ‘engine=INNODB’ D=mydb,t=mytest,h=localhost –execute
如果你本来就工作在row格式下,那么–set-vars ‘binlog_format=ROW’就可以不设置了.
3)复制环境下,忽略日志筛选和Slave复制延迟,删除表字段
pt-online-schema-change
–no-check-replication-filters –recursion-method=none –alter “drop
company_type,drop channel_code”
h=192.168.10.14,P=3370,u=user1,p=pass1,D=db1,t=table1 –print –statistics
–execute
4)更新被子表引用到的父表
pt-online-schema-change
–alter “add newcol int”
h=192.168.10.14,P=3370,u=user1,p=pass1,D=db1,t=table1
–alter-foreign-keys-method auto –print –statistics –execute
5)在我们的双主复制环境中,设定了忽略mysql库的复制,不是很在乎复制的延迟,有时有外键影响,希望尽量保留原表数据,必要时自行删除。
pt-online-schema-change
–no-check-replication-filters –recursion-method=none –alter “drop
newcol” h=192.168.10.14,P=3370,u=user1,p=pass1,D=db1,t=table1
–alter-foreign-keys-method auto –no-drop-old-table –print –statistics
–execute
6)修改表结构的一个字段大小
pt-online-schema-change --user=root --host=127.0.0.1 --password=123456 --alter "CHANGE hardware_num hardware_num VARCHAR(64) NOT NULL DEFAULT ‘‘" --set-vars wait_timeout=10000,innodb_lock_wait_timeout=10,lock_wait_timeout=120 --max-load=Threads_running=16 --critical-load=Threads_running=50 D=db1,t=table1 --chunk-size 2000 --nodrop-old-table --execute
本文出自 “孜孜不倦的学习着...” 博客,请务必保留此出处http://jonyisme.blog.51cto.com/3690784/1761553
Percona Toolkit 使用(五)(pt-online-schema-change)
标签:pt-online-schema-change pt-toolkit
原文地址:http://jonyisme.blog.51cto.com/3690784/1761553