mysql鎖表分析

由於近期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事務,更新數據,且不提交索引

執行結果以下:事務

  1. 修改表結構

  1. 開啓D事務,更新數據

執行時會發現表被鎖住了.

  1. 將C事務提交或者回滾,這裏我選擇了回滾

7)C事務釋放鎖後,D事務更改爲功,可是耗時很長。

結論與建議:

在執行alter table 操做時,事務會由並行變爲串行,同時只能有一個事務更新表數據。儘可能選擇流量小的時候執行alter 語句。而且要注意避開跑批等耗時較長的更新操做。在執行時最好先看一下有沒有未提交的事務。

 

  • 更新單條語句
    MYSQL的鎖是加在索引上的,若是update 語句中的where 未使用到索引,即會鎖表。

按以下步驟執行測試:

Dsfp_order_jnl表 busi_serial字段不存在索引。

1)開啓A事務,更新數據,且不提交

執行結果以下

 

2)開啓B事務,更新數據,且不提交

B事務更新時鎖超時。

結論與建議:

update語句必須使用索引,哪怕是更新很快的操做,否則在併發高時同樣會致使問題。

 

 

  • 數據集合使用索引
    mysql對於數據集合使用索引時,存在內部優化策略,當你選擇的數據範圍較大時,會放棄使用索引,而掃描全表,若是是select for update,update,delete等操做就會鎖定全表,影響業務。

範圍數據有沒有使用索引咱們可使用explain查詢。

  1. 較小數據範圍

Possible_keys表示查詢可能使用哪些索引,key表示mysql決定採用哪一個索引對查詢進行優化。Type range表示這是一個範圍掃描。

  1. 擴大數據範圍

此時雖然可使用索引,可是mysql最終選擇了全表掃描。 type 爲all,key爲null.

對於查詢咱們能夠強制mysql放棄內部優化,使用咱們指定的索引。

  1. 使用強制索引

Update 語句與select 語句可使用相同的處理方式。

  1. 更新不使用強制索引

 

  1. 更細使用強制索引

Delete 語句不支持force index語法,咱們可使用limit 語句替代,limit語句會優先使用索引查找數據

  1. Delete不使用limit

  1. Delete使用limit

結論與建議:

在對批量數據進行操做時,先到生產環境或者1b1環境,對要執行的SQL進行一次explain看是否使用了索引。 select for update,update 可使用force_index。Delete 可使用limit。

相關文章
相關標籤/搜索