Step 1: Create the new table. Step 2: Alter the new, empty table. This should be very quick, or die if the user specified a bad alter statement. Step 3: Create the triggers to capture changes on the original table and apply them to the new table. 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. DROP TABLE IF EXISTS `_xx_old` DROP TRIGGER IF EXISTS `pt_osc_xx_xx_del`; DROP TRIGGER IF EXISTS `pt_osc_xx_xx_upd`; DROP TRIGGER IF EXISTS `pt_osc_xx_xx_ins`; done
inception調用pt-online-schema-change,相關參數以下: inception_osc_alter_foreign_keys_method = rebuild_constraints inception_osc_check_alter = on inception_osc_check_interval = 5 inception_osc_check_replication_filters = OFF inception_osc_chunk_size = 1000 inception_osc_chunk_size_limit = 4 inception_osc_chunk_time = 1 inception_osc_critical_thread_connected = 4000 inception_osc_critical_thread_running = 300 inception_osc_drop_new_table = on inception_osc_drop_old_table = on inception_osc_max_lag = 3 inception_osc_max_thread_connected = 2500 inception_osc_max_thread_running = 200 inception_osc_min_table_size = 16 inception_osc_recursion_method = none 以上inception參數對應的pt-online-schema-change的命令參數以下: pt-online-schema-change --alter " xx " --alter-foreign-keys-method=rebuild_constraints --check-alter=yes --check-interval=5 --check-replication-filters=no --chunk-size=1000 --chunk-size-limit=4 --chunk-time=1 --critical-load=thread_connected:4000,thread_running:300 --max-load=thread_connected:2500,thread_running:200 --drop-new-table=yes --drop-old-table=yes --max-lag=3 --recursion-method=none
默認狀況下,pt-online-schema-change 是不會修改表的,除非你顯示的指定了 --execute
pt-online-schema-change 有一系列動做來阻住一切不指望的後果發生,包括 自動檢測複製,以及如下相關措施javascript
經過這個選項,就不須要alter table關鍵字了。 你能夠經過逗號來指定多個修改操做。java
* 如下列出--alter中的一些限制,你們謹記和避免
1. 原表必需要有主鍵或惟一鍵,由於delete觸發器須要用到,不然會報錯 2. rename子句,不容許給表重命名 2.1 不能經過刪除一列,而後再新增一列的方式來完成對列的重命名操做 3. 新增字段,若是這個字段是NOT NULL,必需要指定default值,不然報錯。 你必須指定默認值 4. 若是是DROP FOREIGN KEY constraint_name , 那麼必須指定 _ 加上 constraint_name , 而不是 constraint_name。 舉例: CONSTRAINT `fk_foo` FOREIGN KEY (`foo_id`) REFERENCES `bar` (`foo_id`) 你必須指定: --alter "DROP FOREIGN KEY _fk_foo" 而不是 --alter "DROP FOREIGN KEY fk_foo". 5. 必須確保數據庫高於5.0版本,由於5.0版本轉換MYSIAM到InnoDB會出錯
默認yes, 給--alter 作一些檢測python
* 列的重命名
在以前的版本 CHANGE COLUMN name new_name 這個操做是會丟失數據的,如今的工具修復了
可是,因爲pt代碼並非full-blown SQL parser,因此,你應該先 --dry-run and --print , 確認下renamed的列名是否正確,以確保無誤 * 刪除主鍵 刪除主鍵是很危險的事情,儘可能不要作這樣的動做
咱們的規範不容許有外鍵,若是有外鍵,咱們採起其餘方式DDLsql
如何把外鍵引用到新表?須要特殊處理帶有外鍵約束的表,以保證它們能夠應用到新表.當重命名錶的時候,外鍵關係會帶到重命名後的表上。
該工具備兩種方法,能夠自動找到子表,並修改約束關係。
auto: 在rebuild_constraints和drop_swap兩種處理方式中選擇一個。
rebuild_constraints:使用 ALTER TABLE語句先刪除外鍵約束,而後再添加.若是子表很大的話,會致使長時間的阻塞。 drop_swap: 執行FOREIGN_KEY_CHECKS=0,禁止外鍵約束,刪除原表,再重命名新表。這種方式很快,也不會產生阻塞,可是有風險: 1, 在刪除原表和重命名新表的短期內,表是不存在的,程序會返回錯誤。 2, 若是重命名錶出現錯誤,也不能回滾了.由於原表已經被刪除。 none: 相似"drop_swap"的處理方式,可是它不刪除原表,而且外鍵關係會隨着重命名轉到老表上面。
鏈接實例信息,縮寫-h xxx -u xxx -p xxx,密碼可使用參數--ask-pass 手動輸入。
指定要ddl的數據庫名和表名
最好設置爲MySQL默認字符集: utf8
默認1秒,檢測--max-lag
默認yes數據庫
若是發現任何服務器有 binlog_ignore_db and replicate_do_db , 那麼就報錯
指定一個從庫的DSN鏈接地址,若是從庫超過--max-lag參數設置的值,就會暫停操做。
默認yes。交換原始表和新表,除非你禁止--[no]drop-old-table。
默認1s。
每一個chunk拷貝完成後,會查看全部複製Slave的延遲狀況。
要是延遲大於該值,則暫停複製數據,直到全部從的滯後小於這個值,使用Seconds_Behind_Master。
若是有任何從滯後超過此選項的值,則該工具將睡眠--check-interval指定的時間,再檢查。 若是從被中止,將會永遠等待,直到從開始同步,而且延遲小於該值。 若是指定--check-slave-lag,該工具只檢查該服務器的延遲,而不是全部服務器。
默認爲Threads_running=25。
每一個chunk拷貝完後,會檢查SHOW GLOBAL STATUS的內容,檢查指標是否超過了指定的閾值。 若是超過,則先暫停。 這裏能夠用逗號分隔,指定多個條件, 每一個條件格式: status指標=MAX_VALUE 或者 status指標:MAX_VALUE。 若是不指定MAX_VALUE,那麼工具會設置其爲當前值的120%。
默認爲Threads_running=50。
用法基本與--max-load相似,若是不指定MAX_VALUE,那麼工具會這隻其爲當前值的200%。 若是超過指定值,則工具直接退出,而不是暫停。
打印SQL語句到標準輸出。指定此選項可讓你看到該工具所執行的語句,和--dry-run配合最佳。
複製數據的時候打印進度報告,二部分組成:第一部分是百分比,第二部分是時間。
設置MySQL變量,多個用逗號分割。
默認該工具設置的是: wait_timeout=10000 innodb_lock_wait_timeout=1 lock_wait_timeout=60
默認是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則表示不在意從的延遲。
--pause-file安全
能夠指定文件暫停pt-online-schema-change
1. 禁止建立惟一索引,會丟失數據,更加不容許添加 --alter-check=no,--check-unique-key-change=no 2. 若是原表沒有主鍵,或者也沒有惟一索引,這些表是不容許用pt作DDL的 3. 禁止對外鍵的表進行pt ddl 4. 禁止對錶進行重命名 5. 禁止對列進行重命名,若是必定要作,也必須先print出來檢測清楚列名是否正確 6. 新增字段,NOT NULL必需要指定默認值 7. 不容許刪除主鍵
REPLACE INTO `lc`.`_hb_new` (`id`, `ts`, `ts2`, `c1`) VALUES (NEW.`id`, NEW.`ts`, NEW.`ts2`, NEW.`c1`)
BEGIN DELETE IGNORE FROM `lc`.`_hb_new` WHERE !(OLD.`id` <=> NEW.`id`) AND `lc`.`_hb_new`.`id` <=> OLD.`id`; REPLACE INTO `lc`.`_hb_new` (`id`, `ts`, `ts2`) VALUES (NEW.`id`, NEW.`ts`, NEW.`ts2`); END
update觸發器 =SQL轉換=> delete ignore + replace into (大於3.0.2版本) =SQL轉換=> replace into(低於3.0.2版本,因此這個版本會有問題,若是這時候對老的主鍵修改,那麼修改以前的值不會去掉,從而多了一些異常數據) 舉例:t表中有三條數據,第一列id是主鍵 ------ 1 lc --row1 2 lc --row2 3 lc --row3 ------ pt-online-schema-change的原理大體四個階段: 1. 建立臨時表_t_new 2. 建立觸發器 3. 老數據row copy 4. swap table 好了,咱們來舉個例子: 1. 建立臨時表_t_new 2. 建立觸發器 3. 老數據row copy 3.1 拷貝數據row1,row2完畢 3.2 這時候業務有一個update語句, update t set id = 10 where id=1; 3.3 拷貝數據row3 4. swap table 這時候腦補一下原表和新表的示意圖, 這時候已經執行到3.1階段 老表 ------------ 1 lc --row1 2 lc --row2 3 lc --row3 ------------ 新表 ----------- 1 lc 2 lc ----------- 這時候腦補一下原表和新表的示意圖, 這時候已經執行到3.3階段 老表(update t set id = 10 where id=1) ------------ 10 lc --row1 2 lc --row2 3 lc --row3 ------------ 新表(3.0.2以前版本的觸發器,沒有delete映射,因此最終結果以下,跟老表相比已經不一致了,多了一條數據1,lc) , 觸發器 replace into _t_new(id,name) values(10,lc) ----------- 1 lc 2 lc 10 lc 3 lc ----------- 新表(3.0.2以後版本的觸發器,有delete映射,因此最終結果以下,於老表的數據一致) , 觸發器 delete ignore _t_new where id = 1;replace into _t_new(id,name) values(10,lc); ----------- 2 lc 10 lc 3 lc -----------
遇到錯誤後,繼續補充完整bash