首先不得不在該篇里面梳理一個數據庫熱增加刪除字段表的工具pt-online-schema-change這個工具在前面我的博文 《關於utf8mb4的學習了解筆記》里面有提到過,他是一個online的ddl(data definition language)工具。由於mysql 的ddl語句在執行的時候會鎖表,在數據量大的情況下鎖表就會嚴重影響正常的數據寫入。
既然都說到這里了,也總結一下我在網上查到的innodb在ddl的時候所執行的操作:
1. 按照原始表(original_table)的表結構和ddl語句,新建一個不可見的臨時表(temporary_table)
2. 在原表上面加上WRITE LOCK,阻塞所有的更新操作(insert、delete、update等操作)
3. 執行insert into tmp_table select * from original_table
4. rename original_table和tmp_table,最后drop original_table
5. 最后釋放掉write lock
通過以上的步驟我們可以很容易的發現,這樣操作在表鎖定的情況是只能查詢,不能寫入。為了解決這個問題所以PERCONA公司推出了一個不會阻塞的工具pt-online-schema-change。
這里不得不再次介紹一下pt-online-schema-change是怎么做到在不阻塞寫入的情況下改動數據庫的:
1. 首先創建一個和你要執行的alter操作的表一樣的空的表結構。
2. 執行我們賦予的表結構的修改,然后copy原表中的數據到新表里面。
3. 在原表上創建一個觸發器在數據copy的過程中,將原表的更新數據的操作全部更新到新的表中來。 這里特別注意一下,如果原表中已經定義了觸發器那么工具就不能工作了。
4. copy完成之后,用rename table 新表代替原表,默認刪除原表。
了解了原理之后,理解起來就似乎不那么困難了。感覺這些問題也並不是什么高大上的問題了。下面看看具體使用
pt-online-schema-change h=ip_address,u=user_name,D=database,t=table --alter "add column shop_id int(11) DEFAULT NULL " --set-vars --lock-wait-timeout=3 --ask-pass --execute
以上就是大致語法,這里來介紹幾個參數:
--set-vars:
-
type: string; default: wait_timeout=10000
Set these MySQL variables. Immediately after connecting to MySQL, this string will be appended to SET and executed.
字符串類型,在鏈接到mysql之后立即設置mysql變量,這個變量會給展示這些設置和執行。
- --lock-wait-timeout:
-
type: int; default: 1
Set the session value of innodb_lock_wait_timeout. This option helps guard against long lock waits if the data-copy queries become slow for some reason. Setting this option dynamically requires the InnoDB plugin, so this works only on newer InnoDB and MySQL versions. If the setting’s current value is greater than the specified value, and the tool cannot set the value as desired, then it prints a warning. If the tool cannot set the value but the current value is less than or equal to the desired value, there is no error.
類型int,默認值是1秒
設置一個session值為innodb_lock_wait_timeout.這個選項幫助你防止一個長時間的鎖等待,這種情況一般會發生在比如說數據拷貝的時候,變得非常慢。設置這個選項需要innodb的插件,所以要innodb引擎和mysql比較新。如果設置的這個值比需要的值大,而且這個工具不能設置為一個需要值的話,就會報出warning。反之如果工具不能設置這個值,但是這個值又比所需要的值小的話,就不會發生什么。
--ask-for:
在連接數據庫的時候提示輸入密碼。
--execute參數
只有加了這個參數,才會去真正執行添加觸發器拷貝數據等一系列操作。
其他想要了解更加相信的信息可以訪問這個文檔https://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html 這是官方文檔,基本上疑問都可以從這里得到解答。