MySql Online DDL操作記錄詳解
一、環(huán)境
為支持用戶賬號刪除功能,需要在 user 表上加一個字段 deleted。
數(shù)據(jù)庫:Mysql5.6
被 操作表 user:數(shù)量級為100w,外鍵200多個
操作:alter table user add deleted boolean NOT NULL default false comment '用戶注銷標識' , algorithm=inplace, lock=none;
二、執(zhí)行過程分析
在Mysql5.6之后,mysql支持 Online DDL 操作。
Online DDL Support for Column Operations
Operation | In Place | Rebuilds Table | Permits Concurrent DML | Only Modifies Metadata |
---|---|---|---|---|
Adding a column | Yes | Yes | Yes* | No |
Dropping a column | Yes | Yes | Yes | No |
Renaming a column | Yes | No | Yes* | Yes |
Reordering columns | Yes | Yes | Yes | No |
Setting a column default value | Yes | No | Yes | Yes |
Changing the column data type | No | Yes | No | No |
Dropping the column default value | Yes | No | Yes | Yes |
Changing the auto-increment value | Yes | No | Yes | No* |
Making a column NULL | Yes | Yes* | Yes | No |
Making a column NOT NULL | Yes* | Yes* | Yes | No |
Modifying the definition of an ENUM or SET column | Yes | No | Yes | Yes |
如圖所示,所執(zhí)行的添加列操作整個過程為:
- 初始化:為創(chuàng)建臨時表的表結(jié)構(gòu),獲取MDL的排他鎖
- 執(zhí)行:根據(jù)參數(shù) algorithm=inplace, lock=none ,MDL鎖降級為共享鎖進行數(shù)據(jù)拷貝
- 提交:由于涉及到增量備份和臨時表的重命名,MDL鎖需要升級為排他鎖
分析后認為,整個過程只有在初始化和提交的極短過程內(nèi)需要用到MDL排他鎖(影響線上),故而就直接在線上進行操作嘗試。
三、遇到的問題
在初始化和提交階段需要用到MDL的排他鎖,而如果DDL操作一直沒獲取MDL鎖(默認獲取MDL鎖超時時間為一年),那么就會造成 Waiting for table metadata lock 狀態(tài),也會阻塞后面所有對 user 表的操作(包括select)。后面會看到連接占滿,服務502:
在遇到這樣的問題后,為不影響線上,于是后面進行了工具的嘗試。
四、工具嘗試
工具涉及到 pt-online-schema-change、gh-ost和阿里云無鎖DDL。三個工具大同小異,均為使用臨時表,將原表數(shù)據(jù)拷貝到臨時表,最后將臨時表重命名替換掉原表。區(qū)別是在增量同步方面,一個用的觸發(fā)器、一個用的binlog日志。
但是在處理外鍵方面,pt-online-schema-change用的刪除、重建外鍵,gh-ost和阿里云無鎖DDL則是不支持主表外鍵的變更。eg:阿里云無鎖DDL的失敗嘗試
故使用工具進行 DDL 操作也不適合。
五、Online DDL 嘗試
在本地測試30w數(shù)據(jù)新增列只需440ms后,嘗試選擇了 online ddl 的操作:
設(shè)置 session 級別獲取 MDL 鎖等待時間時間,避免長時間阻塞其他線程
$ set lock_wait_timeout=10; # 在10s內(nèi)獲取不到MDL鎖,直接退出 alter 操作 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
kill 掉對應的線程以及事務
$ select group_concat(stat separator ' ') from (select concat('kill query ',id,';') as stat from information_schema.processlist where command != 'Sleep' and Time > 5 order by Time desc) as stats; +-------------------------------------+ | group_concat(stat separator ' ') | +-------------------------------------+ | kill query 42510; kill query 42514; | +-------------------------------------+ 1 row in set (0.00 sec) $ select group_concat(stat separator ' ') from (select concat('kill ',trx_mysql_thread_id,';') as stat from information_schema.innodb_trx order by trx_started desc) as stats; +-------------------------------------------------------------------------+ | group_concat(stat separator ' ') | +-------------------------------------------------------------------------+ | kill 42436; kill 42435; kill 42521; kill 42511; kill 42510; kill 42483; | +-------------------------------------------------------------------------+ 1 row in set (0.01 sec)
執(zhí)行 DDL 操作:
$ alter table user add deleted boolean NOT NULL default false comment '用戶注銷標識' , algorithm=inplace, lock=none;
結(jié)果:
以上是在停服后操作的結(jié)果,其中 2 操作在停服后,沒有需要 kill 的 ID。
參考文獻
以上就是MySql Online DDL操作記錄詳解的詳細內(nèi)容,更多關(guān)于MySql Online DDL操作的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Sql Server數(shù)據(jù)庫遠程連接訪問設(shè)置詳情
這篇文章主要介紹了Sql Server數(shù)據(jù)庫遠程連接訪問設(shè)置詳情,文章圍繞主題展開詳細的內(nèi)容戒殺,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09草稿整理后mysql兩個數(shù)據(jù)庫結(jié)構(gòu)對比
這篇文章主要為大家詳細介紹了mysql兩個數(shù)據(jù)庫結(jié)構(gòu)對比結(jié)果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02MySQL入門(一) 數(shù)據(jù)表數(shù)據(jù)庫的基本操作
這類文章記錄我看MySQL5.6從零開始學》這本書的過程,將自己覺得重要的東西記錄一下,并有可能幫助到你們,在寫的博文前幾篇度會非?;A(chǔ),只要動手敲,跟著我寫的例子全部實現(xiàn)一遍,基本上就搞定了,前期很難理解的東西基本沒有2018-07-07解決MySQL安裝重裝時出現(xiàn)could not start the service mysql error:0問題的方法
這篇文章主要為大家詳細介紹了解決MySQL安裝重裝時出現(xiàn)could not start the service mysql error:0問題的方法,感興趣的小伙伴們可以參考一下2016-06-06MySQL Aborted connection告警日志的分析
這篇文章主要介紹了MySQL Aborted connection告警日志的分析,幫助大家更好的理解和學習MySQL,感興趣的朋友可以了解下2020-08-08