功能介绍:
功能为在alter操作更改表结构的时候不用锁定表,也就是说执行alter的时候不会阻塞写和读取操作。
注意:执行这个工具的时候必须做好备份,操作之前最好详细读一下官方文档 pt-online-schema-change
工作原理是 : 创建一个新表,在新表上执行表结构修改,然后从原表中copy原始数据到表结构修改后的表,当数据copy完成以后就会将原表移走,用新表代替原表,默认动作是将原表drop掉。在copy数据的过程中,任何在原表的更新操作都会更新到新表,因为这个工具在会在原表上创建触发器,触发器会将在原表上更新的内容更新到新表。如果表中已经定义了触发器这个工具就不能工作了!!
用法介绍:
pt-online-schema-change [OPTIONS] DSN
options可以自行查看help,DNS为你要操作的数据库和表。
注意事项:
1. 在参数配置时,注意是否需要--drop-new-table、--drop-old-table
2. 在添加了--check-slave-lag时候,配置--max-lag,延迟低于--max-lag的时候才继续,多个slave可以使用--recursion-method 参数:
指定--recursion-method="dsn=D=database,t=dsns"
CREATETABLE`dsns`(
`id`int(11) NOT NULL AUTO_INCREMENT,
`parent_id`int(11) DEFAULT NULL,
`dsn`varchar(255) NOT NULL,
PRIMARYKEY(`id`) );
INSERT INTO dsns(parent_id , dsn) VALUES (1, 'h=10.10.1.16,u=*,p=*,P=3306');
INSERT INTO dsns( parent_id , dsn) VALUES (1, 'h=10.10.1.17,u=*,p=*,P=3306');
3. 例如需要更高联合主键为一个id自增主键时,应在一个alter中进行如下操作:
a. 删除复合主键定义
b. 添加新的自增主键
c. 原复合主键字段,修改成唯一索引
在c中,修改成唯一索引的原因:
percona手册里有两个地方对修改主键进行了特殊注解:
–alter
A notable exception is when a PRIMARY KEY or UNIQUE INDEX is being created from existing columns as part of the ALTER clause; in that case it will use these column(s) for the DELETE trigger.
–[no]check-alter
DROP PRIMARY KEY
If –alter contain DROP PRIMARY KEY (case- and space-insensitive), a warning is printed and the tool exits unless –dry-run is specified. Altering the primary key can be dangerous, but the tool can handle it. The tool’s triggers, particularly the DELETE trigger, are most affected by altering the primary key because the tool prefers to use the primary key for its triggers. You should first run the tool with –dry-run and –print and verify that the triggers are correct.
pt-online-schema-change会在原表t1上创建 AFTER DELETE/UPDATE/INSERT 三个触发器,而对于主键的操作,会影响delete触发器,因为新表中没有了yuan
CREATETRIGGER`pt_osc_confluence_sbtest3_del`AFTERDELETEON`confluence`.`sbtest3`FOREACHROWDELETEIGNOREFROM`confluence`.`_sbtest3_new`
WHERE`confluence`.`_sbtest3_new`.`id`<=>OLD.`id`AND`confluence`.`_sbtest3_new`.`k`<=>OLD.`k`
注:sbtest3表上以(id,k)作为复合主键
所以,如果id或k列上没有索引,这个删除的代价非常高,所以一定要同时添加复合(唯一)索引 (id,k) 。如果使用pt-osc去修改删除主键,务必同时添加原主键为 UNIQUE KEY,否则很有可能导致性能问题:
而对于INSERT,UPDATE的触发器,依然是 REPLACE INTO语法,因为它采用的是先插入,如果违反主键或唯一约束,则根据主键或意义约束删除这条数据,再执行插入。(但是注意你不能依赖于新表的主键递增,因为如果原表有update,新表就会先插入这一条,导致id与原表记录所在顺序不一样)
$ pt-online-schema-change --user=user--password=userpwd --host=10.10.10.34 --alter "DROP PRIMARY KEY,add column pk int auto_increment primary key,add unique key uk_id_k(id,k)" D=confluence,t=sbtest3--print --dry-run
--alter contains 'DROP PRIMARY KEY'. Dropping and altering the primary key can be dangerous,
especially if the original table does not have other unique indexes. ==>注意 dry-run的输出
ALTERTABLE`confluence`.`_sbtest3_new`DROPPRIMARYKEY,addcolumnpkintauto_increment primarykey,adduniquekeyuk_id_k(id,k)
Altered`confluence`.`_sbtest3_new`OK.
UsingoriginaltableindexPRIMARYfortheDELETEtriggerinsteadofnewtableindexPRIMARY because ==> 使用原表主键值判断
the new table index uses column pk which does not exist in the original table.
CREATETRIGGER`pt_osc_confluence_sbtest3_del`AFTERDELETEON`confluence`.`sbtest3`FOREACHROWDELETEIGNOREFROM`confluence`.`_sbtest3_new`
WHERE`confluence`.`_sbtest3_new`.`id`<=>OLD.`id`AND`confluence`.`_sbtest3_new`.`k`<=>OLD.`k`
4. 主键有0值时,需要注意pt-online-schema-change会设置 SQL_MODE中NO_AUTO_VALUE_ON_ZERO!!!
LP #1709650: pt-online-schema-change eating portion of a table
使用示例:
范例1:在线更改表的的引擎,这个尤其在整理innodb表的时候非常有用,示例如下:
pt-online-schema-change --user=root --password=wang@123 --host=localhost --lock-wait-time=120 --alter="ENGINE=InnoDB" D=test,t=oss_pvinfo2 --execute
从下面的日志中可以看出它的执行过程:
Altering
`test`.`oss_pvinfo2`...
Creating new
table...
Created new table
test._oss_pvinfo2_new OK.
Altering new
table...
Altered
`test`.`_oss_pvinfo2_new` OK.
Creating triggers...
Created triggers OK.
Copying approximately
995696 rows...
Copied
rows OK.
Swapping
tables...
Swapped
original and new tables OK.
Dropping
old table... Dropped old table `test`.`_oss_pvinfo2_old` OK.
Dropping
triggers... Dropped triggers OK.
Successfully
altered `test`.`oss_pvinfo2`.
相关报错:
1. 在对大表进行结构变更时,报错退出:
pt-online-schema-change 3.0.4
MySQL 5.7.17
执行语句为:
pt-online-schema-change --alter "add column addr varchar(200)" --print --charset utf8 --chunk-size=50000 --max-load Threads_running=100 --recurse=1 --alter-foreign-keys-method=none --force --execute --statistics --max-lag 3.000000 --noversion-check --recursion-method=processlist --progress percentage,1 D=osc,t=test
报错信息如下:
......
Copying `osc`.`test`: 34% 02:05:40 remain
# Exiting on SIGHUP.
Not dropping triggers because the tool was interrupted. To drop the triggers, execute:
DROP TRIGGER IF EXISTS `osc`.`pt_osc_osc_test_del`
DROP TRIGGER IF EXISTS `osc`.` pt_osc_osc_test_upd`
DROP TRIGGER IF EXISTS `osc`.` pt_osc_osc_test_ins`
Not dropping the new table `osc`.`_test_new` because the tool was interrupted. To drop the new table, execute:
DROP TABLE IF EXISTS `osc`.`_test_new`;
由于没有具体的报错信息,只有一个:# Exiting on SIGHUP.
猜测可能是由于资源不够导致的,因为毕竟都已经执行到了:Copying `osc`.`test`: 34% 02:05:40 remain
---->所以调整Threads_running=50,再次进行测试,没有再出现这个问题,done!