程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL數據庫鎖機制

MySQL數據庫鎖機制

編輯:MySQL綜合教程

MySQL數據庫鎖機制     所謂鎖,為保證數據的一致性,對共享資源的在被並發訪問變得有序的一種規則。         不同的MySQL存儲引擎,有不同的鎖機制或鎖實現;總的來所,使用了三種鎖級別,行級鎖(row-level)、頁級鎖(page-level)、表級鎖(table-level),依次鎖定的資源粒度逐漸減小,鎖資源是隨著鎖定資源粒度的減小,鎖定同樣數據需要的內存數量越來越多,算法也越來越負責,但同時應用程序遇到鎖等待的可能也越來越底,系統的整體並發行隨之提高;          表級鎖,各大存儲引擎粒度最大的鎖級別,實現簡單,獲取鎖和釋放鎖的速度快,也避免了死鎖的問題,但同時帶來了鎖資源競爭的問題,導致並發度較底;表級鎖分為讀鎖和寫鎖,MySQL通過四個隊列來維護這兩種鎖定,兩個存放當前正被鎖定中的讀和寫的信息,兩個存放等待讀和寫的信息,這四個隊列分別為:read->lock\read_wait->lock->write->lock/write_wait->lock;讀鎖定,當前請求獲取鎖定的資源沒有被寫鎖定,也沒有在寫鎖定等待隊列中有優先級更高寫鎖等待,立即進入read->lock,如果不滿足,進入read_wait->lock;寫鎖定,當前請求寫的資源沒有被寫鎖定,並且沒有在寫鎖定等待隊列裡面,那麼再檢測是否在讀等待隊列裡面,如果有,進入寫等待隊列,如果沒有,進入當前寫隊列;使用表級鎖的通常是一些非事務性的存儲引擎,如MyISAM、Memory、CSV等         頁級鎖,MySQL中畢竟特殊的一種鎖級別,粒度介於行級鎖和表級鎖之間,獲取和釋放鎖資源的負擔也介於行級鎖和表級鎖之間,並發性同樣也介於行級鎖和表級鎖之間,和行級鎖一樣,頁級鎖也可能發生死鎖;主要是BerkeleyDB存儲引擎是鎖定方式;         行級鎖,是RMDB實現的鎖定粒度最小的鎖,發生資源競爭的概率最小,能夠給提供盡可能大的並發處理從而提供應用的性能。但同時由於顆粒度小,導致獲取和釋放鎖需要的消耗也最大。另外,行級鎖最容易發生死鎖;行級鎖定不是由MySQL實現的,而是由存儲引擎實現的,如InnoDB和MySQL的分布式存儲引擎NDBCluster等;InnoDB的行級鎖同樣分為兩種,共享鎖和排他鎖,同樣InnoDB也引入了意向鎖(表級鎖)的概念,所以也就有了意向共享鎖和意向排他鎖,所以InnoDB實際上有四種鎖,即共享鎖(S)、排他鎖(X)、意向共享鎖(IS)、意向排他鎖(IX);         如果某些資源已經有了一個共享鎖,那麼在這些資源上面可以添加其他的共享鎖,但不能添加排他鎖;如果某些資源已經有了一個排他鎖,那麼在這些資源上不能添加其他的排他鎖和共享鎖,只能等待當前鎖的釋放,並獲取鎖資源後,才能對其加鎖,但可以對其添加意向鎖,即如果等待事務想要添加的是排他鎖,那麼可以在鎖定行的所在表添加意向排他鎖,如果等待事務想要添加的是共享鎖,那麼可以在鎖定行所在表添加意向共享鎖;InnoDB的鎖實現與Oracle的鎖實現有很大的不同,總的來說,Oracle鎖定數據是根據某行記錄所在的物理block上的事務槽上表級鎖定信息,而InnoDB的鎖定則是通過指向數據記錄的第一條索引之前和最後一條索引之後的空域空間上標記鎖信息來實現的,所以InnoDB的這種鎖實現有被稱為“Next Key Locking”(間隙鎖),間隙鎖一個比較大的弱點是,當鎖定一定范圍的鍵值後,即使一些不存在的鍵值也回被無辜的鎖定,導致這種鍵值的記錄不能被insert。當然,這種情況只會出現在InnoDB的默認的事務隔離級別repeatable-read才會出現,如果降低InnoDB的事務隔離級別為read commited則不會出現這樣的情況。InnoDB給出的解釋是間隙鎖可以阻止幻讀的出現,但其實間隙鎖只能阻止部分幻讀的情況,但不能阻止全部。通過索引來實現鎖的方式還有一個更大的隱患是,當Query不能使用索引時,行級鎖將會上升為表級鎖,會將整張數據表鎖住,造成並發性能的降低。         死鎖,行級鎖可能產生死鎖,InnoDB也不例外。InnoDB有一套檢測死鎖的機制,但前提是死鎖的場景涉及的存儲引擎都是InnoDB的時候。如果InnoDB檢測到死鎖的存在,那麼就將影響數據行數最小的個事務回滾。         那麼有什麼辦法來避免InnoDB的間隙鎖帶來的麻煩嗎?有三種辦法:1、降低並發,避免出現資源競爭,但這樣會在一定程度上降低應用的性能;2、修改InnoDB的默認的事務隔離級別,由repeatable-read修改為read commited,當然修改事務隔離級別帶來的另外一個隱患就是可能會出現不可重復讀;3、在查詢數據是,一定要使用索引,避免全表掃描,在insert數據時,使用增長的索引字段(即每次插入的索引字段的值一定保證是增長的);   相關文檔: http://www.BkJia.com/database/201202/118620.html http://www.BkJia.com/database/201202/120824.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved