mysql:pt-online-schema-change 線上修改表
阿新 • • 發佈:2018-12-06
pt-online-schema-change
名字:pt-online-schema-change - ALTER tables without locking them. 線上改表
下載地址:
https://www.percona.com/downloads/percona-toolkit/3.0.12/binary/redhat/6/x86_64/percona-toolkit-3.0.12-1.el6.x86_64.rpm
https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html#downloading
官方文件:https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html
1.首先了解一下pt-online-schema-change工作原理,其實原理很簡單
1、如果存在外來鍵,根據alter-foreign-keys-method引數的值,檢測外來鍵相關的表,做相應設定的處理。沒有使用 --alter-foreign-keys-method 指定特定的值,該工具不予執行 2、建立一個新的表,表結構為修改後的資料表,用於從源資料表向新表中匯入資料。 3、建立觸發器,用於記錄從拷貝資料開始之後,對源資料表繼續進行資料修改的操作記錄下來,用於資料拷貝結束後,執行這些操作,保證資料不會丟失。如果表中已經定義了觸發器這個工具就不能工作了。 4、拷貝資料,從源資料表中拷貝資料到新表中。 5、修改外來鍵相關的子表,根據修改後的資料,修改外來鍵關聯的子表。 6、rename源資料表為old表,把新表rename為源表名,並將old表刪除。 7、刪除觸發器。
2.使用方法:
pt-online-schema-change [OPTIONS] DSN 具體說下 OPTIONS 的一些常用的引數: 複製程式碼 --user: -u,連線的使用者名稱 --password: -p,連線的密碼 --database: -D,連線的資料庫 --port -P,連線資料庫的埠 --host: -h,連線的主機地址 --socket: -S,連線的套接字檔案 --ask-pass 隱式輸入連線MySQL的密碼 --charset 指定修改的字符集 --defaults-file -F,讀取配置檔案 --alter: 結構變更語句,不需要alter table關鍵字。可以指定多個更改,用逗號分隔。如下場景,需要注意: 不能用RENAME來重命名錶。 列不能通過先刪除,再新增的方式進行重新命名,不會將資料拷貝到新列。 如果加入的列非空而且沒有預設值,則工具會失敗。即其不會為你設定一個預設值,必須顯示指定。 刪除外來鍵(drop foreign key constrain_name)時,需要指定名稱_constraint_name,而不是原始的constraint_name。 如:CONSTRAINT `fk_foo` FOREIGN KEY (`foo_id`) REFERENCES `bar` (`foo_id`),需要指定:--alter "DROP FOREIGN KEY _fk_foo" --alter-foreign-keys-method 如何把外來鍵引用到新表?需要特殊處理帶有外來鍵約束的表,以保證它們可以應用到新表.當重命名錶的時候,外來鍵關係會帶到重新命名後的表上。 該工具有兩種方法,可以自動找到子表,並修改約束關係。 auto: 在rebuild_constraints和drop_swap兩種處理方式中選擇一個。 rebuild_constraints:使用 ALTER TABLE語句先刪除外來鍵約束,然後再新增.如果子表很大的話,會導致長時間的阻塞。 drop_swap: 執行FOREIGN_KEY_CHECKS=0,禁止外來鍵約束,刪除原表,再重新命名新表。這種方式很快,也不會產生阻塞,但是有風險: 1, 在刪除原表和重新命名新表的短時間內,表是不存在的,程式會返回錯誤。 2, 如果重命名錶出現錯誤,也不能回滾了.因為原表已經被刪除。 none: 類似"drop_swap"的處理方式,但是它不刪除原表,並且外來鍵關係會隨著重新命名轉到老表上面。 --[no]check-alter 預設yes,語法解析。配合--dry-run 和 --print 一起執行,來檢查是否有問題(change column,drop primary key)。 --max-lag 預設1s。每個chunk拷貝完成後,會檢視所有複製Slave的延遲情況。要是延遲大於該值,則暫停複製資料,直到所有從的滯後小於這個值,使用Seconds_Behind_Master。如果有任何從滯後超過此選項的值,則該工具將睡眠--check-interval指定的時間,再檢查。如果從被停止,將會永遠等待,直到從開始同步,並且延遲小於該值。如果指定--check-slave-lag,該工具只檢查該伺服器的延遲,而不是所有伺服器。 --check-slave-lag 指定一個從庫的DSN連線地址,如果從庫超過--max-lag引數設定的值,就會暫停操作。 --recursion-method 預設是show processlist,發現從的方法,也可以是host,但需要在從上指定report_host,通過show slave hosts來找到,可以指定none來不檢查Slave。 METHOD USES =========== ================== processlist SHOW PROCESSLIST hosts SHOW SLAVE HOSTS dsn=DSN DSNs from a table none Do not find slaves 指定none則表示不在乎從的延遲。 --check-interval 預設是1。--max-lag檢查的睡眠時間。 --[no]check-plan 預設yes。檢查查詢執行計劃的安全性。 --[no]check-replication-filters 預設yes。如果工具檢測到伺服器選項中有任何複製相關的篩選,如指定binlog_ignore_db和replicate_do_db此類。發現有這樣的篩選,工具會報錯且退出。因為如果更新的表Master上存在,而Slave上不存在,會導致複製的失敗。使用–no-check-replication-filters選項來禁用該檢查。 --[no]swap-tables 預設yes。交換原始表和新表,除非你禁止--[no]drop-old-table。 --[no]drop-triggers 預設yes,刪除原表上的觸發器。 --no-drop-triggers 會強制開啟 --no-drop-old-table 即:不刪除觸發器就會強制不刪除原表。 --new-table-name 複製建立新表的名稱,預設%T_new。 --[no]drop-new-table 預設yes。刪除新表,如果複製組織表失敗。 --[no]drop-old-table 預設yes。複製資料完成重新命名之後,刪除原表。如果有錯誤則會保留原表。 --max-load 預設為Threads_running=25。每個chunk拷貝完後,會檢查SHOW GLOBAL STATUS的內容,檢查指標(thread)是否超過了指定的閾值。如果超過,則先暫停。這裡可以用逗號分隔,指定多個條件,每個條件格式:status指標=MAX_VALUE或者status指標:MAX_VALUE。如果不指定MAX_VALUE,那麼工具會指定其為當前值的120%。 --critical-load 預設為Threads_running=50。用法基本與--max-load類似,如果不指定MAX_VALUE,那麼工具會指定其為當前值的200%。如果超過指定值,則工具直接退出,而不是暫停。 --default-engine 預設情況下,新的表與原始表是相同的儲存引擎,所以如果原來的表使用InnoDB的,那麼新表將使用InnoDB的。在涉及複製某些情況下,很可能主從的儲存引擎不一樣。使用該選項會預設使用預設的儲存引擎。 --set-vars 設定MySQL變數,多個用逗號分割。預設該工具設定的是: wait_timeout=10000 innodb_lock_wait_timeout=1 lock_wait_timeout=60 --chunk-size-limit 當需要複製的塊遠大於設定的chunk-size大小,就不復制.預設值是4.0,一個沒有主鍵或唯一索引的表,塊大小就是不確定的。 --chunk-time 在chunk-time執行的時間內,動態調整chunk-size的大小,以適應伺服器效能的變化,該引數設定為0,或者指定chunk-size,都可以禁止動態調整。 --chunk-size 指定塊的大小,預設是1000行,可以新增k,M,G字尾.這個塊的大小要儘量與--chunk-time匹配,如果明確指定這個選項,那麼每個塊就會指定行數的大小. --[no]check-plan 預設yes。為了安全,檢查查詢的執行計劃.預設情況下,這個工具在執行查詢之前會先EXPLAIN,以獲取一次少量的資料,如果是不好的EXPLAIN,那麼會獲取一次大量的資料,這個工具會多次執行EXPALIN,如果EXPLAIN不同的結果,那麼就會認為這個查詢是不安全的。 --statistics 打印出內部事件的數目,可以看到複製資料插入的數目。 --dry-run 建立和修改新表,但不會建立觸發器、複製資料、和替換原表。並不真正執行,可以看到生成的執行語句,瞭解其執行步驟與細節。--dry-run與--execute必須指定一個,二者相互排斥。和--print配合最佳。 --execute 確定修改表,則指定該引數。真正執行。--dry-run與--execute必須指定一個,二者相互排斥。 --print 列印SQL語句到標準輸出。指定此選項可以讓你看到該工具所執行的語句,和--dry-run配合最佳。 --progress 複製資料的時候列印進度報告,二部分組成:第一部分是百分比,第二部分是時間。 --quiet -q,不把資訊標準輸出。
3.安裝
下載最新的pt-online-schema-change
[[email protected] data]# wget https://www.percona.com/downloads/percona-toolkit/3.0.12/binary/redhat/6/x86_64/percona-toolkit-3.0.12-1.el6.x86_64.rpm
安裝
[[email protected] data]# rpm -ivh percona-toolkit-3.0.12-1.el6.x86_64.rpm
warning: percona-toolkit-3.0.12-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY
error: Failed dependencies:
perl(DBI) >= 1.13 is needed by percona-toolkit-3.0.12-1.el6.x86_64
perl(DBD::mysql) >= 1.0 is needed by percona-toolkit-3.0.12-1.el6.x86_64
perl(Time::HiRes) is needed by percona-toolkit-3.0.12-1.el6.x86_64
perl(IO::Socket::SSL) is needed by percona-toolkit-3.0.12-1.el6.x86_64
perl(Term::ReadKey) is needed by percona-toolkit-3.0.12-1.el6.x86_64
安裝相關的依賴包:
[[email protected] data]# yum install perl-TermReadKey.x86_64
[[email protected] data]# yum install perl-DBI
[[email protected] data]# yum install perl-DBD-MySQL
[[email protected] data]# yum install perl-Time-HiRes
[[email protected] data]# yum install perl-IO-Socket-SSL
然後再次安裝
[[email protected] data]# rpm -ivh percona-toolkit-3.0.12-1.el6.x86_64.rpm
warning: percona-toolkit-3.0.12-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY
Preparing... ########################################### [100%]
1:percona-toolkit ########################################### [100%]
至此軟體已經安裝好,下面就通過測試來了解如何使用該工具
建立測試資料
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',name varchar(20) DEFAULT '' COMMENT '使用者名稱',PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者表';
Query OK, 0 rows affected (0.04 sec)
mysql> insert into users(name) values('test1'),('test2'),('test3');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| users |
+----------------+
1 row in set (0.00 sec)
mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
在正式使用之前,再次瞭解一下常用的幾個引數:
--nocheck-replication-filters :不檢查複製過濾器,建議啟用。
--no-check-binlog-format : 不檢查複製的binlog模式,要是binlog模式是ROW,則會報錯。
--replicate-check-only :只顯示不同步的資訊。
--replicate= :把checksum的資訊寫入到指定表中,建議直接寫到被檢查的資料庫當中。
--chunk-size=50 Number of rows to select for each chunk copied. Allowable suffixes are k, M, G.預設1000
--critical-load="Threads_running=600" 表示執行緒到600自動退出,預設值50
--max-load="Threads_running=100" 表示執行緒到100暫停pt操作,預設25
--progress=time,2 兩秒列印一次日誌輸出
測試各種不同的場景
1.整理表碎片
sql語句:alter table table_name engine=innodb
pt執行語句,以下2種都可以
(1)pt-online-schema-change --alter="engine innodb;" --execute D=test,t=users --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --socket=/tmp/mysql.sock --user=root --password=123 --charset=utf8 --progress=time,2 --chunk-size=100
(2)pt-online-schema-change --alter="engine innodb;" --execute D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --progress=time,2 --chunk-size=100
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="engine innodb;" --execute D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --progress=time,2 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
Created new table test._users_new OK.
Altering new table...
Altered `test`.`_users_new` OK.
2018-12-06T13:28:05 Creating triggers...
2018-12-06T13:28:05 Created triggers OK.
2018-12-06T13:28:05 Copying approximately 3 rows...
2018-12-06T13:28:05 Copied rows OK.
2018-12-06T13:28:05 Analyzing new table...
2018-12-06T13:28:05 Swapping tables...
2018-12-06T13:28:05 Swapped original and new tables OK.
2018-12-06T13:28:05 Dropping old table...
2018-12-06T13:28:05 Dropped old table `test`.`_users_old` OK.
2018-12-06T13:28:05 Dropping triggers...
2018-12-06T13:28:05 Dropped triggers OK.
Successfully altered `test`.`users`.
2.新增欄位:
(1)新增一個欄位
alter table users add age varchar(10) NOT NUll DEFAULT '' COMMENT '性別';
pt語句: pt-online-schema-change --alter="add age varchar(10) NOT NUll DEFAULT '' COMMENT '性別' ;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
具體執行過程
[[email protected] ~]# pt-online-schema-change --alter="add age varchar(10) NOT NUll DEFAULT '' COMMENT '性別' ;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` add age varchar(10) NOT NUll DEFAULT '' COMMENT '��' ;
Altered `test`.`_users_new` OK.
2018-12-06T13:36:55 Creating triggers...
2018-12-06T13:36:55 Created triggers OK.
2018-12-06T13:36:55 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`) SELECT `id`, `name` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17461 copy table*/
2018-12-06T13:36:55 Copied rows OK.
2018-12-06T13:36:55 Analyzing new table...
2018-12-06T13:36:55 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T13:36:55 Swapped original and new tables OK.
2018-12-06T13:36:55 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T13:36:55 Dropped old table `test`.`_users_old` OK.
2018-12-06T13:36:55 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T13:36:55 Dropped triggers OK.
Successfully altered `test`.`users`.
(2)新增2個或多個欄位
sql語句:alter table users add column address varchar(100) default '' comment='地址' after age,add column telephone int default 0 comment='手機號碼';
pt語句:pt-online-schema-change --alter="add column address varchar(100) default '' comment '地址' after age,add column telephone int default 0 comment '手機號碼' after address ;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="add column address varchar(100) default '' comment '地址' after age,add column telephone int default 0 comment '手機號碼' after address ;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`age` varchar(10) NOT NULL DEFAULT '' COMMENT '性別',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` add column address varchar(100) default '' comment 'å�°å��' after age,add column telephone int default 0 comment 'æ��æ�ºå�·ç �' after address ;
Altered `test`.`_users_new` OK.
2018-12-06T14:02:40 Creating triggers...
2018-12-06T14:02:40 Created triggers OK.
2018-12-06T14:02:40 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`, `age`) SELECT `id`, `name`, `age` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17584 copy table*/
2018-12-06T14:02:40 Copied rows OK.
2018-12-06T14:02:40 Analyzing new table...
2018-12-06T14:02:40 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T14:02:40 Swapped original and new tables OK.
2018-12-06T14:02:40 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T14:02:40 Dropped old table `test`.`_users_old` OK.
2018-12-06T14:02:40 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T14:02:40 Dropped triggers OK.
Successfully altered `test`.`users`.
3.修改欄位
sql語句:alter table users modify column address varchar(200) default '' comment '家庭住址';
pt語句: pt-online-schema-change --alter="modify column address varchar(200) default '' comment '家庭住址';" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="modify column address varchar(200) default '' comment '家庭住址';" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`age` varchar(10) NOT NULL DEFAULT '' COMMENT '性別',
`address` varchar(100) DEFAULT '' COMMENT '地址',
`telephone` int(11) DEFAULT '0' COMMENT '手機號碼',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` modify column address varchar(200) default '' comment '家åºä½�å��';
Altered `test`.`_users_new` OK.
2018-12-06T14:08:57 Creating triggers...
2018-12-06T14:08:57 Created triggers OK.
2018-12-06T14:08:57 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`, `age`, `address`, `telephone`) SELECT `id`, `name`, `age`, `address`, `telephone` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17607 copy table*/
2018-12-06T14:08:57 Copied rows OK.
2018-12-06T14:08:57 Analyzing new table...
2018-12-06T14:08:57 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T14:08:57 Swapped original and new tables OK.
2018-12-06T14:08:57 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T14:08:57 Dropped old table `test`.`_users_old` OK.
2018-12-06T14:08:57 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T14:08:57 Dropped triggers OK.
Successfully altered `test`.`users`.
4.新增索引
sql語句:alter table users add index index_age(age);
pt語句:pt-online-schema-change --alter="add index index_age(age);" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="add index index_age(age);" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`age` varchar(10) NOT NULL DEFAULT '' COMMENT '性別',
`address` varchar(200) DEFAULT '' COMMENT '家庭住址',
`telephone` int(11) DEFAULT '0' COMMENT '手機號碼',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` add index index_age(age);
Altered `test`.`_users_new` OK.
2018-12-06T14:11:39 Creating triggers...
2018-12-06T14:11:39 Created triggers OK.
2018-12-06T14:11:39 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`, `age`, `address`, `telephone`) SELECT `id`, `name`, `age`, `address`, `telephone` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17622 copy table*/
2018-12-06T14:11:39 Copied rows OK.
2018-12-06T14:11:39 Analyzing new table...
2018-12-06T14:11:39 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T14:11:39 Swapped original and new tables OK.
2018-12-06T14:11:39 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T14:11:39 Dropped old table `test`.`_users_old` OK.
2018-12-06T14:11:39 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T14:11:39 Dropped triggers OK.
Successfully altered `test`.`users`.
5.刪除索引
sql語句:alter table users drop index index_age;
pt語句: pt-online-schema-change --alter="drop index index_age;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="drop index index_age;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`age` varchar(10) NOT NULL DEFAULT '' COMMENT '性別',
`address` varchar(200) DEFAULT '' COMMENT '家庭住址',
`telephone` int(11) DEFAULT '0' COMMENT '手機號碼',
PRIMARY KEY (`id`),
KEY `index_age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` drop index index_age;
Altered `test`.`_users_new` OK.
2018-12-06T14:13:25 Creating triggers...
2018-12-06T14:13:25 Created triggers OK.
2018-12-06T14:13:25 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`, `age`, `address`, `telephone`) SELECT `id`, `name`, `age`, `address`, `telephone` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17629 copy table*/
2018-12-06T14:13:25 Copied rows OK.
2018-12-06T14:13:25 Analyzing new table...
2018-12-06T14:13:25 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T14:13:25 Swapped original and new tables OK.
2018-12-06T14:13:25 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T14:13:25 Dropped old table `test`.`_users_old` OK.
2018-12-06T14:13:25 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T14:13:25 Dropped triggers OK.
Successfully altered `test`.`users`.
6.修改自增ID
sql語句:alter table users modify column id bigint not null auto_increment;
pt語句: pt-online-schema-change --alter="modify column id bigint not null auto_increment;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="modify column id bigint not null auto_increment;" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100
No slaves found. See --recursion-method if host 18c 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`.`users`...
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者主鍵',
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`age` varchar(10) NOT NULL DEFAULT '' COMMENT '性別',
`address` varchar(200) DEFAULT '' COMMENT '家庭住址',
`telephone` int(11) DEFAULT '0' COMMENT '手機號碼',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` modify column id bigint not null auto_increment;
Altered `test`.`_users_new` OK.
2018-12-06T14:17:35 Creating triggers...
2018-12-06T14:17:35 Created triggers OK.
2018-12-06T14:17:35 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`, `age`, `address`, `telephone`) SELECT `id`, `name`, `age`, `address`, `telephone` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17643 copy table*/
2018-12-06T14:17:35 Copied rows OK.
2018-12-06T14:17:35 Analyzing new table...
2018-12-06T14:17:35 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T14:17:35 Swapped original and new tables OK.
2018-12-06T14:17:35 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T14:17:35 Dropped old table `test`.`_users_old` OK.
2018-12-06T14:17:35 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T14:17:35 Dropped triggers OK.
Successfully altered `test`.`users`.
7.修改列名,並新增索引
sql語句:alter table test change column age ages varchar(5) default '' comment '性別新' after address,add index index_ages(ages);
pt語句:pt-online-schema-change --alter="change column age ages varchar(5) after address,add index index_ages(ages);" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100 --no-check-alter
具體執行過程:
[[email protected] ~]# pt-online-schema-change --alter="change column age ages varchar(5) after address,add index index_ages(ages);" --execute --print --max-lag=5 D=test,t=users,u=root,p=123,S=/tmp/mysql.sock --no-check-replication-filters --max-load="Threads_running=100" --critical-load="Threads_running=120" --charset=utf8 --chunk-size=100 --no-check-alter
No slaves found. See --recursion-method if host 18c 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`.`users`...
Renaming columns:
age to ages
Creating new table...
CREATE TABLE `test`.`_users_new` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`age` varchar(10) NOT NULL DEFAULT '' COMMENT '性別',
`address` varchar(200) DEFAULT '' COMMENT '家庭住址',
`telephone` int(11) DEFAULT '0' COMMENT '手機號碼',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表'
Created new table test._users_new OK.
Altering new table...
ALTER TABLE `test`.`_users_new` change column age ages varchar(5) after address,add index index_ages(ages);
Altered `test`.`_users_new` OK.
2018-12-06T14:55:27 Creating triggers...
2018-12-06T14:55:27 Created triggers OK.
2018-12-06T14:55:27 Copying approximately 3 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_users_new` (`id`, `name`, `ages`, `address`, `telephone`) SELECT `id`, `name`, `age`, `address`, `telephone` FROM `test`.`users` LOCK IN SHARE MODE /*pt-online-schema-change 17822 copy table*/
2018-12-06T14:55:27 Copied rows OK.
2018-12-06T14:55:27 Analyzing new table...
2018-12-06T14:55:27 Swapping tables...
RENAME TABLE `test`.`users` TO `test`.`_users_old`, `test`.`_users_new` TO `test`.`users`
2018-12-06T14:55:27 Swapped original and new tables OK.
2018-12-06T14:55:27 Dropping old table...
DROP TABLE IF EXISTS `test`.`_users_old`
2018-12-06T14:55:27 Dropped old table `test`.`_users_old` OK.
2018-12-06T14:55:27 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_users_ins`
2018-12-06T14:55:27 Dropped triggers OK.
Successfully altered `test`.`users`.
上面做了這麼多的操作,現在來看看測試表已經變成啥模樣了
mysql> show create table users;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| users | CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT '' COMMENT '使用者名稱',
`address` varchar(200) DEFAULT '' COMMENT '家庭住址',
`ages` varchar(5) DEFAULT NULL,
`telephone` int(11) DEFAULT '0' COMMENT '手機號碼',
PRIMARY KEY (`id`),
KEY `index_ages` (`ages`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='使用者表' |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)