1. 程式人生 > >【MySQL技術內幕】34-lock與latch

【MySQL技術內幕】34-lock與latch

這裡還要區分鎖中容易令人混淆的概念lock與 latch。在資料庫中,lock與 latch都可以被稱為“鎖”。但是兩者有著截然不同的含義,本章主要關注的是lock。

latch一般稱為閂鎖(輕量級的鎖),因為其要求鎖定的時間必須非常短。若持續的時間長,則應用的效能會非常差。在 InnoDB儲存引擎中, latch又可以分為 mutex(互斥量)和 relock(讀寫鎖)。其目的是用來保證併發執行緒操作臨界資源的正確性,並且通常沒有死鎖檢測的機制。 lock的物件是事務,用來鎖定的是資料庫中的物件,如表、頁、行。並且一般lock的物件僅在事務 commit或 rollback後進行釋放(不同事務隔離級別釋放的時間可能不同)。此外,lock,正如在大多數資料庫中一樣,是有死鎖機制的。下表顯示了lock與latch的不同。

lock與 latch的比較
lock latch
物件 事務 執行緒
保護 資料庫內容 記憶體資料結構
持續時間 整個事務過程 臨界資源
模式 行鎖、表鎖、意向鎖 讀寫鎖、互斥量
死鎖 通過 waits-for graph、 time out等機制進行無死鎖檢測與處理機制。 無死鎖檢測與處理機制。僅通過應用程式加鎖的順序( lock leveling)保證無死鎖的情況發生
存在於 Lock Manager的雜湊表中 每個資料結構的物件中

對於 InnoDB儲存引擎中的 latch,可以通過命令SHOW ENGINE INNODB MUTEX來進行檢視。

mysql> show engine innodb mutex;
+--------+-----------------------------+----------+
| Type   | Name                        | Status   |
+--------+-----------------------------+----------+
| InnoDB | rwlock: dict0dict.cc:2685   | waits=1  |
| InnoDB | rwlock: dict0dict.cc:1183   | waits=91 |
| InnoDB | rwlock: fil0fil.cc:1381     | waits=1  |
| InnoDB | rwlock: log0log.cc:838      | waits=81 |
| InnoDB | rwlock: btr0sea.cc:195      | waits=1  |
| InnoDB | sum rwlock: buf0buf.cc:1460 | waits=12 |
+--------+-----------------------------+----------+
6 rows in set (0.17 sec)

在 Debug版本下,通過命令SHOW ENGINE INNODB MUTEX可以看到 latch的更多資訊,如圖所示。

通過上述的例子可以看出,列Type顯示的總是 InnoDB,列Name顯示的是 latch的資訊以及所在原始碼的位置(行數)。列 Status比較複雜,在 Debug模式下,除了顯示 os_waits,還會顯示 count、 spin_waits、 spin_rounds、 os_yields、 os_wait_times等資訊。其具體含義見下表。

命令SHOW ENGINE INNODB MUTEX輸出結果說明
名稱 說明
count mutex被請求的次數
spin_waits spin lock(自旋鎖)的次數,InnoDB儲存引擎latch在不能獲得鎖時首先進行自旋,若自旋後還不能獲得鎖,則進入等待狀態
spin_rounds 自旋內部迴圈的總次數,每次自旋的內部迴圈是一個隨機數。 spin rounds/spain waits表示平均每次自旋所需的內部迴圈次數
os_waits 表示作業系統等待的次數。當 spin lock通過自旋還不能獲得 latch時,則會進入作業系統等待狀態,等待被喚醒
os_yields 進行 os_thread_yield喚醒操作的次數
os_wait_times 作業系統等待的時間,單位是ms

上述所有的這些資訊都是比較底層的,一般僅供開發人員參考。但是用息還是可以通過這些引數進行調優。 相對於 latch的檢視,lock資訊就顯得直觀多了。使用者可以通過命令 SHOW ENGINE INNODB STATUS及 information schema架構下的表 INNODB_TRX、 INNODB_LOCKS、INNODB_LOCK_WAITS來觀察鎖的資訊。