天天看點

MySQL metadata lock的前世今生(5.1=>5.7)

最近有同僚經常問到一些metadata lock相關的問題,就順便理一下吧,主要是整理下相關的連接配接和文檔,标題寫的有點大 

MySQL metadata lock的前世今生(5.1=>5.7)

——————————–

不過用過5.5的人都知道,這玩意兒實際上太令人讨厭了,尤其是那陰魂不散的“wait for global read lock”或者“wait for table lock”之類的。當備份時的大查詢,再來個ddl,哐當~故障發生..直接堵死…

不過後面的測試又發現哈希函數有問題,類似類似somedb.someprefix1….somedb.someprefix8的hash key值相同,都被hash到同一個桶下面了.相當于hash分區沒生效。。。。坑!!具體怎麼算的可以看bug#66473後面dmitry lenev的分析。

往後直到mysql5.6.18版本都沒有針對mdl部分的單獨優化;很顯然,後面也不會在5.6版本裡出現了,因為mdl優化已經在5.7.4版本裡展開了。包含3個worklog

簡化dml操作對mdl鎖的持有/釋放;大體思路是把mdl鎖拆分成兩類,一類是dml的mdl(也成為unobtrusive lock),之間互相相容,另一類是ddl的mdl(也稱為obtrusive lock),與其他鎖互斥;

針對dml的mdl,避免了複雜的鎖檢查和對m_waiting/m_granted連結清單的維護,改而使用計數器的方式來實作(稱為fast-path);不過相應的對ddl的mdl鎖的管理邏輯就變的複雜了。沒有細看,貌似fast-path的mdl在遇到沖突時會進行轉換,将其加入到m_granted清單中,并從m_fast_path_state移除

使用lock free的hash對象來管理mdl;由于鎖沖突被移除,是以metadata_locks_hash_instances及metadata_locks_cache_size在之後的版本中可能被棄用;

基本思路是使用lf_hash(lock free hash, 而不是分區的hash)來實作mdl_map

這個實際上是對wl#7304和wl#的進一步優化,針對dml的mdl鎖(也就是所謂fast path),在檢查沖突和釋放時都需要施加m_rwlock鎖,新的改進移除讀寫鎖,改使用原子操作

後續的新的改進計劃目前還沒看到,現在worklog上的更新總要等到實作之後才會更新,讓我們拭目以待吧…