pt-online-schema-change
pt-online-schema-change:官方地址
說明
用途:pt-online-schema-change是Percona工具包的一員,用於修改表而不會造成讀鎖或者寫鎖;
原理
- 根據原表結構創建一個新表;
- 按照pt-osc的alter語句修改新表;
- 將原表中的數據copy到新表中去;
- 將原表copy數據期間的數據更新應用到新表中去(通過觸發器實現);
- 將原表重命名,將新表重命名到原表名稱,默認情況下刪除原表。
# USAGE
pt-online-schema-change --host=xxx.xx.xx.xx --port=xxxx --user=xxxx --ask-pass --charset=utf8 --alter "add column id int not null default 0" D=wing,t=t --execute
優點
執行Alter階段不阻塞讀和寫。
限制
- 原表不能存在觸發器,因爲pt-osc需要通過觸發器將原表copy數據階段產生的數據應用到新表去。
- 表必須具有primary key/unique key,爲了準確應用原表copy數據期間產生的數據到新表中去。通過primary key/unique key定位數據是否存在新表中。
- 原表不能是其他外鍵的父表,需要添加—alter-foreign-keys-method參數即可。
- 字段屬性爲NOT NULL時,必須有DEFAULT屬性,否則會報錯。
常用參數
- –alter
不需要加alter table關鍵字,如pt-online-schema-change --alter "ADD COLUMN c2 INT" D=apple,t=a
限制:
1, 必須要有PRIMARY KEY或者UNIQUE KEY,因爲它會在程序進行的時候創建DELETE 觸發器,來保證新表跟着老表一起更新;
2, RENAME不會被採用去RENAME TABLE
3, 如果增加列的時候指定NOT NULL,並且未提供默認值,則失敗;
4, 如果要刪除外鍵,需要指定 "_constraint_name"而不是 “constraint_name”
5, 如果要將MYISAM表修改爲Innodb會報錯 - –[no]analyze-before-swap 當新表與原表交換的前執行analyze table;
- –ask-pass 連接的時候會要求提供密碼
- –charset 默認字符集
- –[no]check-alter 對於危險的操作會產生告警,如刪除主鍵或者重命名列;
- –check-interval 當主從延時爲–max-lag 秒的時候,檢查sleep的時間;例如設置爲10的時候,主從延時產生,則暫停10秒,再檢查延時,如果依然有有延時,停止10s再檢查; 默認1s
- –[no]check-plan 是否在執行前用EXPLAIN檢查語句
- –[no]check-replication-filters 是否檢查過濾器,如果有任何過濾器的時候,操作都會被放棄;(如:binlog_ignore_db replicate_do_db)
- –check-slave-lag 如果slave的時間戳低於"–max-lag"的時候則暫停操作
- –chunk-index 指定chunk的索引,工具默認會選擇最合適的索引,當然你也可以手動指定
- –chunk-index-columns 有複合索引的時候,指定索引列
- –chunk-size chunk的行數,默認1000
- –chunk-size-limit 默認4,chunk超過應有值的4倍大小則跳過。如果沒有唯一索引,則chunk 大小是不精確的,工具會用EXPLAIN評估大小,如果超過需要chunk大小的n倍,則跳過該chunk;
- –chunk-time 默認0.5, 工具會根據每次複製數據花費的時間自動調整chunk大小,儘可能使每次時間都相同;=0則不調節
- –config 讀取配置文件,多個文件逗號分隔;如果指定則必須是第一個參數
- –critical-load 默認Threads_running=50; 每次chunk執行後會自動用SHOW GLOBAL STATUS檢查負載情況,如果超過閾值則放棄;
- –database -D 指定庫
- –default-engine 該選項將導致新表使用系統默認引擎; 而不是原有表一致的引擎
- –data-dir v 5.6+ 在不同的分區上創建新表
- –remove-data-dir 如果原表已通過–data-dir 創建,該參數會刪除它並在默認datadir下創建新表
- –defaults-file 從文件中讀取選項
- –[no]drop-new-table 如果複製原表失敗則刪除新表; 也可以no-xxx來保留新表
- –[no]drop-old-table rename新表後drop舊錶,可以no-xxx來保留舊錶
- –[no]drop-triggers 刪除舊錶的觸發器;"–no-drop-triggers" forces “–no-drop-old-table”.
- –dry-run 創建並修改新表,但不創建觸發器,也不復製表,或者替換原表,與–execute互斥
- –execute 執行操作 與 --dry-run互斥
- –[no]check-unique-key-change 如果–alter嘗試增加唯一索引的的話,則工具不會運行; 因爲增加唯一索引如果列有重複值,會發生丟失數據的情況;因爲INSERT的時候默認採用"INSERT IGNORE"
- –force 強制運行,可能打破外鍵約束
- –help 幫助
- –host | -h 指定host
- –max-lag 默認1s, 如果主從延時的時間超過這個值,則複製會暫停"–check-interval"秒時間;然後再檢查,直到主從延時小於該值;如果指定了 “–check-slave-lag”,則只會檢查指定slave延時,而不是檢查所有slave;如果有任何SLAVE stop了,那麼工具會一直等待下去;每次停止的時候都會打印報告
- –max-load 默認 : Threads_running=25
每次複製chunk後檢查負載,如果超過該值則暫停;類似–critical-load - –preserve-triggers 保留原表的觸發器,不刪除
- –new-table-name 指定新表的名字,默認是 tablename_new
- –null-to-not-null 修改允許null值爲not null
- –password 指定密碼
- –pause-file 改參數指定的文件存在的時,操作將會暫停
- –pid 新建pid文件
- –port 指定連接端口
- –print 將會顯示工具執行的命令
- –progress 顯示進度,默認: time,30
兩部分組成,第一部分percentage,time或者iterations; 第二部分多久更新一次 - –quiet -q
不打印消息到屏幕; 禁用–progress, ERROR和告警還是會打印 - –recurse
當發現有slave的時候,指定遞歸的層數 , int值 - –recursion-method 查找Slave的遞歸方法
METHOD USES
=========== ==================
processlist SHOW PROCESSLIST
hosts SHOW SLAVE HOSTS
dsn=DSN DSNs from a table
none Do not find slaves - –skip-check-slave-lag 檢查SLAVE的時候,指定該SLAVE跳過;
- –slave-user 設置連接slave的用戶;可以指定用更少權限的用戶連接SLAVE,但是所有slave都必須有該賬戶
- –slave-password --slave-user 的密碼
- –set-vars 默認:
wait_timeout=10000
innodb_lock_wait_timeout=1
lock_wait_timeout=60 - –sleep 複製每個chunk的時候暫停多少s,默認0
- –socket 指定連接socket
- –statistics 打印計數器的數據,當有告警的時候這個參數比較有用
- -[no]swap-tables 指定是否替換舊錶
- –tries 重試次數;
- –user 連接用戶名
- –version 版本
- –[no]version-check 檢查Percona Toolkit的最新版本
使用pt-osc之前需要做的檢查
- 原表是否存在觸發器,存在:no,不存在:yes;
- 原表是否具有pk/uk,不存在:no,存在:yes;
- 原表是否爲其他外鍵的父表,是:—alter-foreign-keys-method=‘xxx’,不是:yes;
- 字段是否爲NOT NULL 屬性,不是:yes,是:DEFAULT;
[外鏈圖片轉存失敗(img-VreJ7QPK-1567990517569)(/img/pt-osc使用前檢查.png)]
具體例子:
可以添加字段、修改字段類型、修改字段名、添加索引
添加字段
[root@localhost tmp]# pt-online-schema-change --alter "ADD COLUMN c3 INT" D=apple,t=a -u root -h localhost -p password --execute
No slaves found. See --recursion-method if host localhost.localdomain has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
# A software update is available:
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 `apple`.`a`...
Creating new table...
Created new table apple._a_new OK.
Altering new table...
Altered `apple`.`_a_new` OK.
2018-09-05T12:57:33 Creating triggers...
2018-09-05T12:57:33 Created triggers OK.
2018-09-05T12:57:33 Copying approximately 2 rows...
2018-09-05T12:57:33 Copied rows OK.
2018-09-05T12:57:33 Analyzing new table...
2018-09-05T12:57:33 Swapping tables...
2018-09-05T12:57:34 Swapped original and new tables OK.
2018-09-05T12:57:34 Dropping old table...
2018-09-05T12:57:34 Dropped old table `apple`.`_a_old` OK.
2018-09-05T12:57:34 Dropping triggers...
2018-09-05T12:57:34 Dropped triggers OK.
Successfully altered `apple`.`a`.
修改字段類型
pt-online-schema-change --alter "MODIFY COLUMN num int(11) unsigned NOT NULL DEFAULT '0'" D=apple,t=a -u root -h localhost -p password --execute
修改字段名
pt-online-schema-change --alter "CHANGE COLUMN age address varchar(30)" D=apple,t=a -u root -h localhost -p password --execute
添加索引
pt-online-schema-change --alter "ADD INDEX idx_address(address)" D=apple,t=a -u root -h localhost -p password --execute
刪除字段
pt-online-schema-change --alter "DROP COLUMN name" D=apple,t=a -u root -h localhost -p password --execute