一、在innodb情況下什麼時候使用表鎖。
對於innodb表,大多數情況都應該使用行鎖,因為事務和行鎖往往是我們選擇innodb表的重要原因。但在特殊的情況下,也可以使用表級鎖。
(1)、事務需要更新大部分資料或者全部資料,表又比較大,如果使用預設的行級鎖,不僅使得事務執行比較慢效率低,而且可能造成其他事務長時間鎖等待和鎖衝突,這樣的情況可以考慮使用表級鎖來提高執行效率。
(2)、事務涉及多個表,又比較複雜,很可能引起死鎖,造成大量事務回滾,可以考慮一次性獲取事務涉及的所有表,從而避免死鎖,減少資料庫因事務回滾產生的開銷。
當然了,應用中這樣的情況不能太多,否則可以考慮換成myisam表了,在innodb下使用表級鎖應該注意以下兩點。
二、死鎖問題。
對於myisam表是不會產生死鎖的,因為表鎖總是一次性獲取所有sql語句涉及到的所有表級鎖。但是在innodb表中,除了單個sql語句組成的事務外,不然鎖都是逐步獲取的。這就讓innodb表產生死鎖的可能。如下是發生死鎖的栗子。
在上面的例子中,兩個事務都需要獲得對方占有的排他鎖才能繼續完成事務,這種迴圈鎖等待就是典型的死鎖。
發生死鎖後,一般情況下innodb都能夠自動檢測到,使乙個事務釋放鎖並退回。另乙個事務獲得鎖,繼續完成事務。但是在設計外部鎖或者表鎖時,innodb無法檢查到死鎖情況,這時需要設定鎖等待超時引數,innodb_lock_wait_timeout來解決。需要說明的是,這個引數不只是用來解決死鎖問題,在併發訪問比較高的情況下,如果大量事務因無法獲得所需的鎖而掛起,會占用計算機大量的資源,造成嚴重效能問題,甚至拖垮資料庫。通過設定合適的鎖等待超時閥值,可以有效避免這樣的情況發生。
通常來說,死鎖都是應用設計的問題,通過調整業務流程,資料庫物件設計,事務大小,以及訪問資料庫sql語句,絕大部分死鎖都可以避免。下面通過例項介紹幾種避免死鎖的常用方法。
(1)、在應用中,如果不同的程式會併發訪問多個表,應盡量以相同的順序來訪問表,這樣可以大大降低產生死鎖的機會,在下面的例子中,兩個session訪問兩個表的順序不同,發生死鎖機會比較高,但是以相同的順序來訪問,死鎖就能避免。
(2)、在程式以批量方式處理資料的時候,如果事先對資料排序,保證每個執行緒按照固定的順序來處理記錄,也大大降低出現死鎖額可能。
3)、在事務中,如果要更新記錄,應該直接申請足夠級別的鎖,即排他鎖。而不應該先申請共享鎖,更新的時候再申請排他鎖。因為當使用者申請排他鎖時,其他事務可能又獲得了相同記錄的共享鎖,從而造成鎖衝突,甚至死鎖。
(4)、在前面的情況中,在repeatable-read隔離級別下,如果兩個執行緒對相同條件記錄用select .... for update 加排他鎖,在沒有符合記錄的條件下,兩個執行緒都會加鎖成功。程式發現記錄尚不存在,就試圖插入一條新紀錄。如果兩個執行緒都折這麼做,就會造成死鎖。這種情況下,將隔離級別改為read commited,就可以避免問題。
5)、當隔離級別為read commited 時,如果兩個執行緒都先執行 select ..... for update ,判斷是否存在符合條件的記錄,如果沒有,就插入記錄,此時,只有乙個執行緒能夠插入成功,另乙個執行緒會出現鎖等待,當第乙個執行緒提交後,第二個執行緒會因主鍵重出錯。但雖然這個執行緒出錯了,卻會獲得乙個排他鎖,這時如果第三個執行緒進來申請排他鎖,也會出現死鎖。
對這樣的情況,可以直接做插入操作,然後再捕獲主鍵重異常,或者遇到主鍵重錯誤時,總是執行rollback釋放獲得的排他鎖。
儘管通過上面的設計和sql優化等措施,可以減少死鎖,但死鎖很難完全避免,因此,在程式設計中,總是捕獲並處理死鎖異常是乙個很好的程式設計習慣。
如果出現死鎖,可以使用show innodb status 命令來檢視最後乙個產生死鎖的原因。返回結果中包含死鎖相關事務的詳細資訊。如引發死鎖的的sql語句,事務已經獲取鎖,正在等待什麼鎖,以及被回滾的事務等。
MySQL InnoDB鎖問題(四)
一 innodb行鎖實現方式。innodb行鎖是通過給索引上的索引項來加鎖實現的,如果沒有索引,innodb將通過隱藏的聚簇索引來對記錄加鎖。innodb行鎖分三種情形。1 record lock 對索引項加鎖。2 grap lock 對索引項之間的 間隙 第一條記錄前的 間隙 或者最後一條記錄後的...
MySQL InnoDB鎖問題(五)
一 next key鎖。當我們使用範圍條件而不是相等條件去檢索資料,並請求共享鎖和排他鎖時,innodb會給符合條件的已有的資料新增上鎖 對於鍵值在條件範圍內,但不存在的記錄,叫間隙。innodb此時會給這個部分新增上鎖,這種鎖機制就是next key鎖。假如 員工表emp中只有101條資料,其em...
Mysql innodb引擎(二)鎖
專案 isixsx is相容 相容相容 不相容ix 相容相容 不相容不相容s相容 不相容相容 不相容x 不相容不相容 不相容不相容 是指 innodb 通過多版本控制的方式來讀取當前執行時間資料庫中的資料。如果,讀取的時候行正好在執行 delete 或 update 的排他操作,那讀取操作不會等待,...