由於近期MYSQL在改表移庫時,發生了鎖表現象.如今對該現象進行分析,並提出一些建議。mysql
1、改表sql
Mysql 5.6 雖然引入了Online DDL,可是並非修改表結構的時候,必定不會致使鎖表,在一些場景下仍是會鎖表的,好比
1)某個慢SQL或者比較大的結果集的SQL在運行,執行ALTER TABLE時將會致使鎖表發生;
2)存在一個事務在操做表的時候,執行ALTER TABLE也會致使修改等待;併發
按以下步驟執行測試:測試
1)開啓A事務,更新數據,且不提交大數據
執行結果以下:優化
2)開啓B事務,更新數據,且不提交3d
這兩條語句互相不影響,將這兩個事務回滾掉,繼續下一輪測試。blog
3)開啓C事務,更新數據,且不提交索引
執行結果以下:事務
執行時會發現表被鎖住了.
7)C事務釋放鎖後,D事務更改爲功,可是耗時很長。
結論與建議:
在執行alter table 操做時,事務會由並行變爲串行,同時只能有一個事務更新表數據。儘可能選擇流量小的時候執行alter 語句。而且要注意避開跑批等耗時較長的更新操做。在執行時最好先看一下有沒有未提交的事務。
按以下步驟執行測試:
Dsfp_order_jnl表 busi_serial字段不存在索引。
1)開啓A事務,更新數據,且不提交
執行結果以下
2)開啓B事務,更新數據,且不提交
B事務更新時鎖超時。
結論與建議:
update語句必須使用索引,哪怕是更新很快的操做,否則在併發高時同樣會致使問題。
範圍數據有沒有使用索引咱們可使用explain查詢。
Possible_keys表示查詢可能使用哪些索引,key表示mysql決定採用哪一個索引對查詢進行優化。Type range表示這是一個範圍掃描。
此時雖然可使用索引,可是mysql最終選擇了全表掃描。 type 爲all,key爲null.
對於查詢咱們能夠強制mysql放棄內部優化,使用咱們指定的索引。
Update 語句與select 語句可使用相同的處理方式。
Delete 語句不支持force index語法,咱們可使用limit 語句替代,limit語句會優先使用索引查找數據
結論與建議:
在對批量數據進行操做時,先到生產環境或者1b1環境,對要執行的SQL進行一次explain看是否使用了索引。 select for update,update 可使用force_index。Delete 可使用limit。