[root@hpaybbcx2:/root]#egrep ‘Step’ /usr/local/bin/pt-online-schema-change
# Step 1: Create the new table.
# Step 2: Alter the new, empty table. This should be very quick,
# Step 3: Create the triggers to capture changes on the original table and
# Step 4: Copy rows.
# Step 5: Rename tables: orig -> old, new -> orig
# Step 6: Update foreign key constraints if there are child tables.
# Step 7: Drop the old table.
三、常用选项说明
–host=xxx –user=xxx –password=xxx
连接实例信息,缩写-h xxx -u xxx -p xxx,密码可以使用参数–ask-pass 手动输入。
–alter
结构变更语句,不需要 ALTER TABLE关键字。与原始ddl一样可以指定多个更改,用逗号分隔。
绝大部分情况下表上需要有主键或唯一索引,因为工具在运行当中为了保证新表也是最新的,需要旧表上创建 DELETE和UPDATE 触发器,同步到新表的时候有主键会更快。个别情况是,当alter操作就是在c1列上建立主键时,DELETE触发器将基于c1列。
子句不支持 rename 去给表重命名。
alter命令不支持给索引重命名,需要先drop再add,在pt-osc也一样。(mysql 5.7 支持 RENAME INDEX old_index_name TO new_index_name);但给字段重命名,千万不要drop-add,整列数据会丢失,使用change col1 col1_new type constraint(保持类型和约束一致,否则相当于修改 column type,不能online)
子句如果是add column并且定义了not null,那么必须指定default值,否则会失败。
如果要删除外键(名 fk_foo),使用工具的时候外键名要加下划线,比如–alter “DROP FOREIGN KEY _fk_foo”
D=db_name,t=table_name <<<<<<注意格式
指定要ddl的数据库名和表名
–max-load
默认为Threads_running=25。每个chunk拷贝完后,会检查 SHOW GLOBAL STATUS 的内容,检查指标是否超过了指定的阈值。如果超过,则先暂停。这里可以用逗号分隔,指定多个条件,每个条件格式: status指标=MAX_VALUE或者status指标:MAX_VALUE。如果不指定MAX_VALUE,那么工具会这只其为当前值的120%。
因为拷贝行有可能会给部分行上锁,Threads_running 是判断当前数据库负载的绝佳指标。
–max-lag
默认1s。每个chunk拷贝完成后,会查看所有复制Slave的延迟情况(Seconds_Behind_Master)。要是延迟大于该值,则暂停复制数据,直到所有从的滞后小于这个值。–check-interval配合使用,指定出现从库滞后超过 max-lag,则该工具将睡眠多长时间,默认1s,再检查。如–max-lag=5 –check-interval=2。
熟悉percona-toolkit的人都知道–recursion-method可以用来指定从库dsn记录。另外,如果从库被停止,将会永远等待,直到从开始同步,并且延迟小于该值。
–chunk-time
默认0.5s,即拷贝数据行的时候,为了尽量保证0.5s内拷完一个chunk,动态调整chunk-size的大小,以适应服务器性能的变化。
也可以通过另外一个选项–chunk-size禁止动态调整,即每次固定拷贝 1k 行,如果指定则默认1000行,且比 chunk-time 优先生效
–set-vars
使用pt-osc进行ddl要开一个session去操作,set-vars可以在执行alter之前设定这些变量,比如默认会设置–set-vars “wait_timeout=10000,innodb_lock_wait_timeout=1,lock_wait_timeout=60”。
因为使用pt-osc之后ddl的速度会变慢,所以预计2.5h只能还不能改完,记得加大wait_timeout。
–dry-run
创建和修改新表,但不会创建触发器、复制数据、和替换原表。并不真正执行,可以看到生成的执行语句,了解其执行 步骤与细节,和–print配合最佳
–execute
确定修改表,则指定该参数。真正执行alter。–dry-run与–execute必须指定一个,二者相互排斥
–chunk-size
默认为1000 row
三、使用疑惑(限制)
3.1原表上不能有触发器存在
这个在mysql 5.7.7+版本得以解决,并且在这个pt版本中也有参数来做支持了
3.2通过触发器写数据到临时新表,会不会出现数据不一致或异常(可能会)
在pt-osc一张表时,有应用发生delete操作,通过trigger触发删除操作,此时old表老数据还没有通过chunk复制到新表中,trigger动作结束后,chunk copy的老数据出现在新表中,导致数据不一致
3.3.为什么外键那么特殊
假设 tb1 是要修改的表,tb2 有外键依赖于 tb1,_tb1_new 是 alter tb1 产生的新临时表。
这里的外键不是看tb1上是否存在外键,而是作为子表的 tb2。主要问题在 rename tb1 时,tb1“不存在”导致tb2的外键认为参考失败,不允许rename。
pt-osc提供–alter-foreign-keys-method选项来决定怎么处理这种情况:
rebuild_constraints,优先采用这种方式
它先通过 alter table tb2 drop fk1,add _fk1 重建外键参考,指向新表
再 rename tb1 tb1_old, _tb1_new tb1 ,交换表名,不影响客户端
删除旧表 tb1_old
但如果字表tb2太大,以致alter操作可能耗时过长,有可能会强制选择 drop_swap。
涉及的主要方法在 pt-online-schema-change 文件的 determine_alter_fk_method, rebuild_constraints, swap_tables三个函数中。
drop_swap,
禁用t2表外键约束检查 FOREIGN_KEY_CHECKS=0
然后 drop tb1 原表
再 rename _tb1_new tb1
这种方式速度更快,也不会阻塞请求。但有风险,
第一,drop表的瞬间到rename过程,原表t1是不存在的,遇到请求会报错;
第二,如果因为bug或某种原因,旧表已删,新表rename失败,那就太晚了,但这种情况很少见。
This method forces –no-swap-tables and –no-drop-old-table.
表间存在外键参考关系,建议不通过表定义强制约束
3.4.使用之前需要对磁盘容量进行评估
使用OSC会使增加一倍的空间,包括索引
而且在 Row Based Replication 下,还会写一份binlog。不要想当然使用–set-vars去设置 sql_log_bin=0,因为在这个session级别,alter语句也要在从库上执行,除非你对从库另有打算。
3.5.使用pt-osc原生5.6 online ddl相比,如何选择
online ddl在必须copy table时成本较高,不宜采用
pt-osc工具在存在触发器时,不适用
修改索引、外键、列名时,优先采用online ddl,并指定 ALGORITHM=INPLACE
其它情况使用pt-osc,虽然存在copy data
pt-osc比online ddl要慢一倍左右,因为它是根据负载调整的
无论哪种方式都选择的业务低峰期执行
特殊情况需要利用主从特性,先alter从库,主备切换,再改原主库
四、操作流程分析1、开启模拟业务
./sysbench --mysql-user=mzhang --mysql-db=ptosc --mysql-password=mzhang --mysql-host=10.148.180.103 --mysql-port=3307 --test=tests/db/oltp.lua --oltp_tables_count=5 --oltp-table-size=1000 --rand-init=on prepare ./sysbench --mysql-user=mzhang --mysql-db=ptosc --mysql-password=mzhang --mysql-host=10.148.180.103 --mysql-port=3307 --test=tests/db/oltp.lua --oltp_tables_count=5 --oltp-table-size=100000 --num-threads=8 --oltp-read-only=off --report-interval=10 --rand-type=uniform --max-time=12000 --max-requests=0 --percentile=99 run
2、通过general log来看pt-osc流程
pt-online-schema-change --host=10.148.180.103 --port=3307 --user=mzhang --password=mzhang \ --alter "add column c5 varchar(8) not null default '' " \ D=ptosc,t=sbtest1 --execute --recursion-method=none
2019-08-06T07:34:06.885522Z 81 Connect mzhang@10.148.180.103 on ptosc using TCP/IP 2019-08-06T07:34:06.885749Z 81 Query set autocommit=1 2019-08-06T07:34:06.885989Z 81 Query SHOW VARIABLES LIKE 'innodb\_lock_wait_timeout' 2019-08-06T07:34:06.887454Z 81 Query SET SESSION innodb_lock_wait_timeout=1 2019-08-06T07:34:06.887606Z 81 Query SHOW VARIABLES LIKE 'lock\_wait_timeout' 2019-08-06T07:34:06.888503Z 81 Query SET SESSION lock_wait_timeout=60 2019-08-06T07:34:06.888652Z 81 Query SHOW VARIABLES LIKE 'wait\_timeout' 2019-08-06T07:34:06.889558Z 81 Query SET SESSION wait_timeout=10000 2019-08-06T07:34:06.889705Z 81 Query SELECT @@SQL_MODE 2019-08-06T07:34:06.889836Z 81 Query SET @@SQL_QUOTE_SHOW_CREATE = 1/*!40101, @@SQL_MODE='NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'*/ 2019-08-06T07:34:06.889968Z 81 Query SELECT @@server_id /*!50038 , @@hostname*/ 2019-08-06T07:34:06.890471Z 82 Connect mzhang@10.148.180.103 on ptosc using TCP/IP 2019-08-06T07:34:06.890581Z 82 Query set autocommit=1 2019-08-06T07:34:06.890749Z 82 Query SHOW VARIABLES LIKE 'innodb\_lock_wait_timeout' 2019-08-06T07:34:06.892091Z 82 Query SET SESSION innodb_lock_wait_timeout=1 2019-08-06T07:34:06.892216Z 82 Query SHOW VARIABLES LIKE 'lock\_wait_timeout' 2019-08-06T07:34:06.893003Z 82 Query SET SESSION lock_wait_timeout=60 2019-08-06T07:34:06.893128Z 82 Query SHOW VARIABLES LIKE 'wait\_timeout' 2019-08-06T07:34:06.893933Z 82 Query SET SESSION wait_timeout=10000 2019-08-06T07:34:06.894017Z 82 Query SELECT @@SQL_MODE 2019-08-06T07:34:06.894098Z 82 Query SET @@SQL_QUOTE_SHOW_CREATE = 1/*!40101, @@SQL_MODE='NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'*/ 2019-08-06T07:34:06.894195Z 82 Query SELECT @@server_id /*!50038 , @@hostname*/ 2019-08-06T07:34:06.894360Z 81 Query SHOW VARIABLES LIKE 'wsrep_on' 2019-08-06T07:34:06.895293Z 81 Query SHOW VARIABLES LIKE 'version%' 2019-08-06T07:34:06.896313Z 81 Query SHOW ENGINES 2019-08-06T07:34:06.896626Z 81 Query SHOW VARIABLES LIKE 'innodb_version' 2019-08-06T07:34:06.897846Z 81 Query SHOW VARIABLES LIKE 'innodb_stats_persistent' 2019-08-06T07:34:06.898858Z 81 Query SHOW GLOBAL STATUS LIKE 'Threads_running' 2019-08-06T07:34:06.899581Z 81 Query SHOW GLOBAL STATUS LIKE 'Threads_running' 2019-08-06T07:34:06.900290Z 81 Query SELECT CONCAT(@@hostname, @@port) 2019-08-06T07:34:06.900556Z 81 Query SHOW TABLES FROM `ptosc` LIKE 'sbtest1' 2019-08-06T07:34:06.900740Z 81 Query SELECT VERSION() 2019-08-06T07:34:06.900853Z 81 Query SHOW TRIGGERS FROM `ptosc` LIKE 'sbtest1' <<<查看操作表上是否已存在触发器 2019-08-06T07:34:06.901211Z 81 Query /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */ 2019-08-06T07:34:06.901287Z 81 Query USE `ptosc` 2019-08-06T07:34:06.901423Z 81 Query SHOW CREATE TABLE `ptosc`.`sbtest1` 2019-08-06T07:34:06.901574Z 81 Query /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */ 2019-08-06T07:34:06.901907Z 81 Query EXPLAIN SELECT * FROM `ptosc`.`sbtest1` WHERE 1=1 2019-08-06T07:34:06.902262Z 81 Query SELECT table_schema, table_name FROM information_schema.key_column_usage WHERE referenced_table_schema='ptosc' AND referenced_table_name='sbtest1' 2019-08-06T07:34:06.921415Z 81 Query SHOW VARIABLES LIKE 'wsrep_on' 2019-08-06T07:34:06.922466Z 81 Query /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */ 2019-08-06T07:34:06.922531Z 81 Query USE `ptosc` 2019-08-06T07:34:06.922608Z 81 Query SHOW CREATE TABLE `ptosc`.`sbtest1` 2019-08-06T07:34:06.922733Z 81 Query /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */ 2019-08-06T07:34:06.922906Z 81 Query CREATE TABLE `ptosc`.`_sbtest1_new` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=99995 DEFAULT CHARSET=utf8 MAX_ROWS=1000000 <<<<基于老表的定义创建一个新表与其结构一样 2019-08-06T07:34:06.956386Z 81 Query ALTER TABLE `ptosc`.`_sbtest1_new` add column c5 varchar(8) not null default '' <<<<在新表上添加新字段 2019-08-06T07:34:07.002789Z 81 Query /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */ 2019-08-06T07:34:07.002903Z 81 Query USE `ptosc` 2019-08-06T07:34:07.003017Z 81 Query SHOW CREATE TABLE `ptosc`.`_sbtest1_new` 2019-08-06T07:34:07.003216Z 81 Query /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */ 2019-08-06T07:34:07.003833Z 81 Query SELECT TRIGGER_SCHEMA, TRIGGER_NAME, DEFINER, ACTION_STATEMENT, SQL_MODE, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, EVENT_MANIPULATION, ACTION_TIMING FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_MANIPULATION = 'DELETE' AND ACTION_TIMING = 'AFTER' AND TRIGGER_SCHEMA = 'ptosc' AND EVENT_OBJECT_TABLE = 'sbtest1' 2019-08-06T07:34:07.004407Z 81 Query SELECT TRIGGER_SCHEMA, TRIGGER_NAME, DEFINER, ACTION_STATEMENT, SQL_MODE, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, EVENT_MANIPULATION, ACTION_TIMING FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_MANIPULATION = 'UPDATE' AND ACTION_TIMING = 'AFTER' AND TRIGGER_SCHEMA = 'ptosc' AND EVENT_OBJECT_TABLE = 'sbtest1' 2019-08-06T07:34:07.004843Z 81 Query SELECT TRIGGER_SCHEMA, TRIGGER_NAME, DEFINER, ACTION_STATEMENT, SQL_MODE, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, EVENT_MANIPULATION, ACTION_TIMING FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_MANIPULATION = 'INSERT' AND ACTION_TIMING = 'AFTER' AND TRIGGER_SCHEMA = 'ptosc' AND EVENT_OBJECT_TABLE = 'sbtest1' 2019-08-06T07:34:07.005313Z 81 Query SELECT TRIGGER_SCHEMA, TRIGGER_NAME, DEFINER, ACTION_STATEMENT, SQL_MODE, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, EVENT_MANIPULATION, ACTION_TIMING FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_MANIPULATION = 'DELETE' AND ACTION_TIMING = 'BEFORE' AND TRIGGER_SCHEMA = 'ptosc' AND EVENT_OBJECT_TABLE = 'sbtest1' 2019-08-06T07:34:07.005749Z 81 Query SELECT TRIGGER_SCHEMA, TRIGGER_NAME, DEFINER, ACTION_STATEMENT, SQL_MODE, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, EVENT_MANIPULATION, ACTION_TIMING FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_MANIPULATION = 'UPDATE' AND ACTION_TIMING = 'BEFORE' AND TRIGGER_SCHEMA = 'ptosc' AND EVENT_OBJECT_TABLE = 'sbtest1' 2019-08-06T07:34:07.006234Z 81 Query SELECT TRIGGER_SCHEMA, TRIGGER_NAME, DEFINER, ACTION_STATEMENT, SQL_MODE, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, EVENT_MANIPULATION, ACTION_TIMING FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_MANIPULATION = 'INSERT' AND ACTION_TIMING = 'BEFORE' AND TRIGGER_SCHEMA = 'ptosc' AND EVENT_OBJECT_TABLE = 'sbtest1' <<<<再次仔细检查是否相关DELETE,UPDATE,INSERT AFTER|BEFOR触发器信息 2019-08-06T07:34:07.006630Z 81 Query CREATE TRIGGER `pt_osc_ptosc_sbtest1_del` AFTER DELETE ON `ptosc`.`sbtest1` FOR EACH ROW DELETE IGNORE FROM `ptosc`.`_sbtest1_new` WHERE `ptosc`.`_sbtest1_new`.`id` <=> OLD.`id` 2019-08-06T07:34:07.033552Z 81 Query CREATE TRIGGER `pt_osc_ptosc_sbtest1_upd` AFTER UPDATE ON `ptosc`.`sbtest1` FOR EACH ROW BEGIN DELETE IGNORE FROM `ptosc`.`_sbtest1_new` WHERE !(OLD.`id` <=> NEW.`id`) AND `ptosc`.`_sbtest1_new`.`id` <=> OLD.`id`;REPLACE INTO `ptosc`.`_sbtest1_new` (`id`, `k`, `c`, `pad`) VALUES (NEW.`id`, NEW.`k`, NEW.`c`, NEW.`pad`);END 2019-08-06T07:34:07.034996Z 81 Query CREATE TRIGGER `pt_osc_ptosc_sbtest1_ins` AFTER INSERT ON `ptosc`.`sbtest1` FOR EACH ROW REPLACE INTO `ptosc`.`_sbtest1_new` (`id`, `k`, `c`, `pad`) VALUES (NEW.`id`, NEW.`k`, NEW.`c`, NEW.`pad`)<<<<<创建触发器,这里注意update时,pt做了两件事情分别在新表里删除操作记录,然后在replace into一条记录 2019-08-06T07:34:07.036635Z 81 Query EXPLAIN SELECT * FROM `ptosc`.`sbtest1` WHERE 1=1 2019-08-06T07:34:07.037567Z 81 Query SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) ORDER BY `id` LIMIT 1 /*first lower boundary*/ 2019-08-06T07:34:07.037877Z 81 Query SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `ptosc`.`sbtest1` FORCE INDEX (`PRIMARY`) WHERE `id` IS NOT NULL ORDER BY `id` LIMIT 1 /*key_len*/ 2019-08-06T07:34:07.098227Z 81 Query EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ * FROM `ptosc`.`sbtest1` FORCE INDEX (`PRIMARY`) WHERE `id` >= '1' /*key_len*/ 这个过程是个循环过程 2019-08-06T07:34:07.112361Z 81 Query EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1')) ORDER BY `id` LIMIT 999, 2 /*next chunk boundary*/ <<<按照约定chunk来查询数据,减少后续锁持有范围 2019-08-06T07:34:07.112558Z 81 Query SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1')) ORDER BY `id` LIMIT 999, 2 /*next chunk boundary*/ 2019-08-06T07:34:07.113002Z 81 Query EXPLAIN SELECT `id`, `k`, `c`, `pad` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1')) AND ((`id` <= '1000')) LOCK IN SHARE MODE /*explain pt-online-schema-change 133584 copy nibble*/ 2019-08-06T07:34:07.113349Z 81 Query INSERT LOW_PRIORITY IGNORE INTO `ptosc`.`_sbtest1_new` (`id`, `k`, `c`, `pad`) SELECT `id`, `k`, `c`, `pad` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1')) AND ((`id` <= '1000')) LOCK IN SHARE MODE /*pt-online-schema-change 133584 copy nibble*/ <<<<向新表中批量插入数据 2019-08-06T07:34:07.190021Z 81 Query SHOW WARNINGS 2019-08-06T07:34:07.190352Z 81 Query SHOW GLOBAL STATUS LIKE 'Threads_running' <<检查一次批量后,mysql thread running负载情况,满足条件,继续下批量循环 2019-08-06T07:34:07.192028Z 81 Query EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1001')) ORDER BY `id` LIMIT 6526, 2 /*next chunk boundary*/ 2019-08-06T07:34:07.192349Z 81 Query SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1001')) ORDER BY `id` LIMIT 6526, 2 /*next chunk boundary*/ 2019-08-06T07:34:07.194379Z 81 Query EXPLAIN SELECT `id`, `k`, `c`, `pad` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1001')) AND ((`id` <= '20450')) LOCK IN SHARE MODE /*explain pt-online-schema-change 133584 copy nibble*/ 2019-08-06T07:34:07.194697Z 81 Query INSERT LOW_PRIORITY IGNORE INTO `ptosc`.`_sbtest1_new` (`id`, `k`, `c`, `pad`) SELECT `id`, `k`, `c`, `pad` FROM `ptosc`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1001')) AND ((`id` <= '20450')) LOCK IN SHARE MODE /*pt-online-schema-change 133584 copy nibble*/ 2019-08-06T07:34:07.416409Z 81 Query SHOW WARNINGS 2019-08-06T07:34:07.416753Z 81 Query SHOW GLOBAL STATUS LIKE 'Threads_running' ..... 2019-08-06T07:34:07.771898Z 81 Query SHOW VARIABLES LIKE 'version%' 2019-08-06T07:34:07.773669Z 81 Query SHOW ENGINES 2019-08-06T07:34:07.773975Z 81 Query SHOW VARIABLES LIKE 'innodb_version' 2019-08-06T07:34:07.775721Z 81 Query ANALYZE TABLE `ptosc`.`_sbtest1_new` /* pt-online-schema-change */ <<<收集新表统计信息 2019-08-06T07:34:07.779636Z 81 Query RENAME TABLE `ptosc`.`sbtest1` TO `ptosc`.`_sbtest1_old`, `ptosc`.`_sbtest1_new` TO `ptosc`.`sbtest1` <<<rename 表,交换表名 2019-08-06T07:34:07.783906Z 81 Query DROP TABLE IF EXISTS `ptosc`.`_sbtest1_old` <<<默认删除操作后的老表 2019-08-06T07:34:07.807794Z 81 Query DROP TRIGGER IF EXISTS `ptosc`.`pt_osc_ptosc_sbtest1_del` 2019-08-06T07:34:07.808163Z 81 Query DROP TRIGGER IF EXISTS `ptosc`.`pt_osc_ptosc_sbtest1_upd` 2019-08-06T07:34:07.808467Z 81 Query DROP TRIGGER IF EXISTS `ptosc`.`pt_osc_ptosc_sbtest1_ins` <<<<删除pt-osc工具创建的trigger 2019-08-06T07:34:07.808877Z 81 Query SHOW TABLES FROM `ptosc` LIKE '\_sbtest1\_new' <<<查看表结构信息 2019-08-06T07:34:07.809315Z 82 Quit 2019-08-06T07:34:07.809400Z 81 Quit
3、表常用修改操作
如果要验证查看将
–execute 替换成–print –dry-run
添加删除索引
pt-online-schema-change --host=10.148.180.103 --port=3307 --user=mzhang --password=mzhang \ --alter "DROP KEY idx_01, ADD KEY idx_02(c5) " \ D=ptosc,t=sbtest1 --execute --recursion-method=none
添加列字段
pt-online-schema-change --host=10.148.180.103 --port=3307 --user=mzhang --password=mzhang \ --alter "add column c5 varchar(8) not null default '' " \ D=ptosc,t=sbtest1 --execute --recursion-method=none
修改列类型
pt-online-schema-change --host=10.148.180.103 --port=3307 --user=mzhang --password=mzhang \ --alter "CHANGE c5 varchar(60) NOT NULL DEFAULT '' " \ D=ptosc,t=sbtest1 --execute --recursion-method=none
修改删除主键
使用pt-osc去修改删除主键,务必同时添加原主键为 UNIQUE KEY,否则触发delete操作时很有可能导致性能问题
DELETE 触发器:新表上_sbtest1_new的主键字段在旧表sbtest1上不存在,无法根据主键条件触发删除新表_sbtest1_new数据,所以pt-osc修改了trigger
非沙删除主键:CREATE TRIGGER `pt_osc_ptosc_sbtest1_del` AFTER DELETE ON `ptosc`.`sbtest1` FOR EACH ROW DELETE IGNORE FROM `ptosc`.`_sbtest1_new` WHERE `ptosc`.`_sbtest1_new`.`id` <=> OLD.`id`
CREATE TRIGGER `pt_osc_ptosc_sbtest1_del` AFTER DELETE ON `ptosc`.`sbtest1` FOR EACH ROW DELETE IGNORE FROM `ptosc`.`_sbtest1_new` WHERE `ptosc`.`_sbtest1_new`.`id` <=> OLD.`id` AND `ptosc`.`_sbtest1_new`.`k` <=> OLD.`k`
pt-online-schema-change --host=10.148.180.103 --port=3307 --user=mzhang --password=mzhang \ --alter "DROP PRIMARY KEY,add column pk int auto_increment primary key,add unique key uk_id_k(id,k)" \ D=ptosc,t=sbtest1 --execute --recursion-method=none