導讀:html
上篇文章講過MySQL原生的Online DDL仍是有不少限制的,仍是會遇到data meta lock的問題等諸多不便,而後就有了咱們今天的話題,經過pt-osc在線執行DDL。數據庫
1、pt-osc的工做原理微信
一、建立一個和源表同樣表結構的新表app
二、在新表執行DDL語句(空表嘛,因此。。。)工具
三、在源表建立三個觸發器分別對應insert、update、delete操做性能
四、從源表拷貝數據到新表,拷貝過程當中源表經過觸發器把新的DML操做更新到新表中this
五、rename源表到old表中,把新表rename爲源表,默認最後刪除源表.net
2、pt-osc工具的限制code
1、源表不能有觸發器存在orm
顯然不是不能有任何觸發器,只是不能有針對insert、update、delete的觸發器存在,由於一個表上不能有兩個相同類型的觸發器
2、源表必需要有主鍵
源表沒有主鍵會報錯:
Cannot chunk the original table `houyi`.`ga`: There is no good index and the table is oversized. at ./pt-online-schema-change line 5353.
3、源表有外鍵,必須使用--alter-foreign-keys-method指定特定的值
3、pt-osc與原生MySQL5.6 Online DDL對比
l Online DDL在必須copy table時成本較高,不宜採用
l Pt-osc在存在觸發器時,不適用
l 其餘狀況使用pt-osc
l 選擇在業務低峯期進行online ddl
4、pt-osc經常使用參數
--host=xxx --user=xxx --password=xxx
鏈接實例信息,縮寫-h xxx -u xxx -p xxx,密碼可使用參數--ask-pass 手動輸入。
--alter
結構變動語句,不須要 ALTER TABLE關鍵字。與原始ddl同樣能夠指定多個更改,用逗號分隔。
D=db_name,t=table_name
指定要ddl的數據庫名和表名
--dry-run
建立和修改新表,但不會建立觸發器、複製數據、和替換原表。並不真正執行,能夠看到生成的執行語句,瞭解其執行步驟與細節,和--print配合最佳。。
--execute
肯定修改表,則指定該參數。真正執行alter。–dry-run與–execute必須指定一個,兩者相互排斥
5、pt-osc使用示例
1、添加新列
[root@bogon ~]# pt-online-schema-change --user=root --password=123456 --host=localhost --alter "add column age int(4) default 0" D=test,t=test01 --print --execute No slaves found. See --recursion-method if host bogon has slaves. Not checking slave lag because no slaves were found and --check-slave-lag was not specified. Operation, tries, wait: analyze_table, 10, 1 copy_rows, 10, 0.25 create_triggers, 10, 1 drop_triggers, 10, 1 swap_tables, 10, 1 update_foreign_keys, 10, 1 Altering `test`.`test01`... Creating new table... CREATE TABLE `test`.`_test01_new` ( `name` varchar(3) DEFAULT NULL, `id` varchar(4) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 Created new table test._test01_new OK. Altering new table... ALTER TABLE `test`.`_test01_new` add column age int(4) default 0 Altered `test`.`_test01_new` OK. 2016-11-30T02:54:32 Creating triggers... CREATE TRIGGER `pt_osc_test_test01_del` AFTER DELETE ON `test`.`test01` FOR EACH ROW DELETE IGNORE FROM `test`.`_test01_new` WHERE `test`.`_test01_new`.`id` <=> OLD.`id` CREATE TRIGGER `pt_osc_test_test01_upd` AFTER UPDATE ON `test`.`test01` FOR EACH ROW REPLACE INTO `test`.`_test01_new` (`name`, `id`) VALUES (NEW.`name`, NEW.`id`) CREATE TRIGGER `pt_osc_test_test01_ins` AFTER INSERT ON `test`.`test01` FOR EACH ROW REPLACE INTO `test`.`_test01_new` (`name`, `id`) VALUES (NEW.`name`, NEW.`id`) 2016-11-30T02:54:32 Created triggers OK. 2016-11-30T02:54:32 Copying approximately 4 rows... INSERT LOW_PRIORITY IGNORE INTO `test`.`_test01_new` (`name`, `id`) SELECT `name`, `id` FROM `test`.`test01` LOCK IN SHARE MODE /*pt-online-schema-change 21439 copy table*/ 2016-11-30T02:54:32 Copied rows OK. 2016-11-30T02:54:32 Analyzing new table... 2016-11-30T02:54:32 Swapping tables... RENAME TABLE `test`.`test01` TO `test`.`_test01_old`, `test`.`_test01_new` TO `test`.`test01` 2016-11-30T02:54:32 Swapped original and new tables OK. 2016-11-30T02:54:32 Dropping old table... DROP TABLE IF EXISTS `test`.`_test01_old` 2016-11-30T02:54:32 Dropped old table `test`.`_test01_old` OK. 2016-11-30T02:54:32 Dropping triggers... DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test01_del`; DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test01_upd`; DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test01_ins`; 2016-11-30T02:54:32 Dropped triggers OK. Successfully altered `test`.`test01`.
2、修改列類型
[root@bogon ~]# pt-online-schema-change h=localhost,P=3306,u=root,p=123456,D=test,t=test01 --alter "change women age int(4) default 0" --print --execute --no-check-alter
3、添加刪除索引
[root@bogon ~]# pt-online-schema-change h=localhost,P=3306,u=root,D=test,t=test01 --ask-pass --alter "drop key index_name,add key index_age(age)" --print --execute
4、修改主鍵
使用pt-osc去修改刪除主鍵,務必同時添加原主鍵爲 UNIQUE KEY,不然頗有可能致使性能問題
[root@bogon ~]# pt-online-schema-change h=localhost,u=root,p=123456,D=test,t=test01 --alter "drop primary key,add primary key(age)" --print --execute --no-check-alter
7、報錯案例
1、報錯語句
The tool should handle this correctly, but you should test it first because if it fails the renamed columns' data will be lost! Specify --no-check-alter to disable this check and perform the --alter.
介個直接看着報錯就能夠解決了
2、報錯語句
The table `db_name`.`table_name` has triggers. This tool needs to create its own triggers, so the table cannot already have triggers.
存在觸發器,表不能存在觸發器
4、pt-osc產生死鎖
當一個事務在作DDL操做,一個事務在作DML操做,有可能會形成死鎖
5、pt-osc致使丟表
當在作DDL的時候,還未提交,此時若是實例crash,就會致使表丟失。
參考文檔:
https://my.oschina.net/kings0/blog/807871
http://www.cnblogs.com/zengkefu/category/854034.html
http://www.dataguru.cn/article-3460-1.html
https://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
爲了方便你們交流,本人開通了微信公衆號,和QQ羣291519319。喜歡技術的一塊兒來交流吧