- 高性能MySQL(第4版)
- (美)Silvia Botros等
- 1000字
- 2023-11-24 18:39:32
鎖的粒度
一種提高共享資源并發性的方式就是讓鎖定對象更有選擇性。盡量只鎖定包含需要修改的部分數據,而不是所有的資源。更理想的方式是,只對需要修改的數據片段進行精確的鎖定。任何時候,讓鎖定的數據量最小化,理論上就能保證在給定資源上同時進行更改操作,只要被修改的數據彼此不沖突即可。
問題是加鎖也需要消耗資源。鎖的各種操作,包括獲取鎖、檢查鎖是否空閑、釋放鎖等,都會增加系統的開銷。如果系統花費大量的時間來管理鎖,而不是存取數據,那么系統的性能可能會受影響。
鎖定策略是鎖開銷和數據安全性之間的平衡,這種平衡會影響性能。大多數商業數據庫系統沒有提供太多的選擇,一般都是在表中施加行級鎖(row level lock),為了在鎖比較多的情況下盡可能地提供更好的性能,鎖的實現方式非常復雜。鎖是數據庫實現一致性保證的方法。數據庫操作專家必須深入源代碼,才能確定合適的配置,以優化速度與數據安全之間的平衡。
而MySQL則提供了多種選擇。每種MySQL存儲引擎都可以實現自己的鎖策略和鎖粒度。在設計存儲引擎時,鎖的管理是一個非常重要的決定。將鎖粒度固定在某個級別,可以提高某些應用場景下的性能,但同時會使其不適合另外一些應用場景。好在MySQL提供了多種存儲引擎,而不是單一的通用解決方案。下面讓我們來看兩種最重要的鎖策略。
表鎖
表鎖(table lock)是MySQL中最基本也是開銷最小的鎖策略。表鎖非常類似于前文描述的電子表格的鎖機制:它會鎖定整張表。當客戶端想對表進行寫操作(插入、刪除、更新等)時,需要先獲得一個寫鎖,這會阻塞其他客戶端對該表的所有讀寫操作。只有沒有人執行寫操作時,其他讀取的客戶端才能獲得讀鎖,讀鎖之間不會相互阻塞。
表鎖有一些變體,可以在特定情況下提高性能。例如,READ LOCAL表鎖支持某些類型的并發寫操作。寫鎖隊列和讀鎖隊列是分開的,但寫鎖隊列的優先級絕對高于讀隊列。[3]
行級鎖
使用行級鎖(row lock)可以最大程度地支持并發處理(也帶來了最大的鎖開銷)。回到電子表格的類比,行級鎖等同于鎖定電子表格中的某一行。這種策略允許多人同時編輯不同的行,而不會阻塞彼此。這使得服務器可以執行更多的并發寫操作,帶來的代價則是需要承擔更多開銷,以跟蹤誰擁有這些行級鎖、已經鎖定了多長時間、行級鎖的類型,以及何時該清理不再需要的行級鎖。
行級鎖是在存儲引擎而不是服務器中實現的。服務器通常[4]不清楚存儲引擎中鎖的實現方式。在本章的后續內容甚至整本書中都可以看到,每種存儲引擎都以自己的方式來實現鎖。