MySQL鎖——MyISAM鎖

MySQL鎖機制:不同的存儲引擎支持不同的鎖機制。

  1. 表級鎖:開銷小、加鎖快;不會出現死鎖;鎖粒度大,發生鎖衝突的概率高,併發度低。
  2. 頁面鎖:性能和併發性都介於表級鎖和行級鎖之間。
  3. 行級鎖:開銷大、加鎖慢;會出現死鎖;鎖粒度小,發生鎖衝突的概率低,併發度高。

由於鎖的特點不同,不同的鎖機制適合不同的應用:
a. 表級鎖適合於以查詢爲主,只有少量按照索引更新的應用,如web應用。
b. 行級鎖適合於有大量按索引條件併發更新少量不同數據,同時又有併發查詢的應用。

MyISQM表鎖:
table_locks_waited狀態變量表示不能立即加鎖,需要等待鎖的次數,也就意味着鎖等待。
table_locks_immediate狀態變量表示可以立即獲得鎖的次數
table_locks_waited/table_locks_immediate值越高說明數據庫的併發性越低,當該值達到一定程度,改用InnoDB存儲引擎。
MySQL MyISAM的表鎖:表共享讀鎖和表獨佔寫鎖

對MyISAM表的讀操作不會阻塞其他用戶對錶的讀請求,但是會阻塞對MyISAM表的寫請求;對MyISAM表的寫操作會阻塞其他用戶對錶的讀請求和寫請求。

MyISAM在執行查詢語句(select)前會自動給所有涉及的表加表共享讀鎖,在執行更新操作(update、delete、insert)前會自動給所有涉及的表加表獨佔寫鎖。

顯式加鎖:

        讀鎖:lock table t read;
            或者
             lock table t read local;
        寫鎖:lock table t write;

因爲MySQL不支持鎖升級,加鎖時需要取得所有涉及表的表鎖,所以加鎖之後,此會話在釋放鎖之前只能操作被加鎖的表,這就是爲什麼MyISAM的表鎖不會出現死鎖。

此外,如果對錶加讀鎖,當前用戶只能對鎖定表執行查詢(select)語句,其他用戶可以對錶加讀鎖,但是不可以對此表加寫鎖,也就是說只能對該表查詢(select),不能更新(update、insert 、delete);如果對錶加寫鎖,當前用戶可以對鎖定的表做任何操作,其他用戶不可以對此表加任何鎖,也就是說不可以對該表執行任何(select、update、insert、delete )操作。

MyISAM表下lock table t read和lock table t read local的區別:
當前對話lock table t read local後,根據concurrent_insert參數的值決定其他用戶可不可以併發插入。但是如果可以動態插入,不會影響當前對話的查詢結果。
concurrent_insert參數:
值爲0:不允許併發插入
值爲1:如果MyISAM表中沒有空洞(表的中間沒有被刪的行),允許在表尾併發插入
值爲2:不論有沒有空洞都允許在表尾併發插入

MyISAM的鎖調度:
MyISAM中,寫進程比讀進程會優先獲得鎖,從而可能到出現大量的更新操作使得查詢操作很難獲得讀鎖,造成讀進程餓死,同樣如果正在執行一個耗時的查詢操作,也可能出現寫進程餓死的情況。
解決方法:
1 》通過設置調度行:
通過制定insert、update、delete語句的low_priority屬性,調整更新語句的優先級。
2 》通過給系統參數max_write_lock_count設置一個合適的值,當一個表的讀鎖達到這個值後,MySQL就會降低寫鎖請求的優先級,給讀進程獲得資源的機會。
3 》將複雜的SQL查詢語句分解爲若干個耗時較小的SQL語句。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章