官术网_书友最值得收藏!

多版本并發控制

MySQL的大多數事務型存儲引擎使用的都不是簡單的行級鎖機制。它們會將行級鎖和可以提高并發性能的多版本并發控制(MVCC)技術結合使用。不僅是MySQL,包括Oracle、PostgreSQL以及其他一些數據庫系統也都使用了MVCC,但各自的實現機制不盡相同,因為MVCC如何工作沒有統一的標準。

可以認為MVCC是行級鎖的一個變種,但是它在很多情況下避免了加鎖操作,因此開銷更低。根據其實現方式,不僅實現了非阻塞的讀操作,寫操作也只鎖定必要的行。

MVCC的工作原理是使用數據在某個時間點的快照來實現的。這意味著,無論事務運行多長時間,都可以看到數據的一致視圖,也意味著不同的事務可以在同一時間看到同一張表中的不同數據!如果你之前沒有這方面的概念,這句話聽起來可能有點讓人迷惑,熟悉了以后你會發現還是很容易理解的。

每個存儲引擎實現MVCC的方式都不同。其中一些變體包括樂觀并發控制和悲觀并發控制。我們可以通過圖1-2所示的序列圖解釋InnoDB的行為[11],以此來展示MVCC的一種實現方式。

圖1-2:跨不同事務處理同一行多個版本的序列圖

InnoDB通過為每個事務在啟動時分配一個事務ID來實現MVCC。該ID在事務首次讀取任何數據時分配。在該事務中修改記錄時,將向Undo日志寫入一條說明如何恢復該更改的Undo記錄,并且事務的回滾指針指向該Undo日志記錄。這就是事務如何在需要時執行回滾的方法。

當不同的會話讀取聚簇主鍵索引記錄時,InnoDB會將該記錄的事務ID與該會話的讀取視圖進行比較。如果當前狀態下的記錄不應可見(更改它的事務尚未提交),那么Undo日志記錄將被跟蹤并應用,直到會話達到一個符合可見條件的事務ID。這個過程可以一直循環到完全刪除這一行的Undo記錄,然后向讀取視圖發出這一行不存在的信號。

事務中的記錄可以通過在記錄的“info flags”中設置“deleted”位來刪除。這在Undo日志中也被作為“刪除標記”進行跟蹤。

值得注意的是,所有Undo日志寫入也都會寫入Redo日志,因為Undo日志寫入是服務器崩潰恢復過程的一部分,并且是事務性的。[12]這些Redo日志和Undo日志的大小也是高并發事務工作機制中的重要影響因素。我們將在第5章更詳細地介紹它們的配置。

在記錄中保留這些額外信息帶來的結果是,大多數讀取查詢都不再需要獲取鎖。它們只是盡可能快地讀取數據,確保僅查詢符合條件的行即可。缺點是存儲引擎必須在每一行中存儲更多的數據,在檢查行時需要做更多的工作,并處理一些額外的內部操作。

MVCC僅適用于REPEATABLE READ和READ COMMITTED隔離級別。READ UNCOMMITTED與MVCC不兼容[13],是因為查詢不會讀取適合其事務版本的行版本,而是不管怎樣都讀最新版本。SERIALIZABLE與MVCC也不兼容,是因為讀取會鎖定它們返回的每一行。

主站蜘蛛池模板: 建始县| 观塘区| 福安市| 石台县| 吴忠市| 呼玛县| 长寿区| 秦皇岛市| 游戏| 靖西县| 安福县| 剑川县| 河间市| 安仁县| 安国市| 安吉县| 宁明县| 措勤县| 元江| 东阳市| 肥西县| 龙泉市| 灯塔市| 凤台县| 饶河县| 青浦区| 石门县| 瑞安市| 调兵山市| 林口县| 平度市| 芦溪县| 德惠市| 息烽县| 宁南县| 遂平县| 莒南县| 清丰县| 隆回县| 招远市| 沧源|