在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

你是否對MySQL數據庫中的事務已經有所了解呢?

jf_ro2CN3Fa ? 來源:頭條 ? 2023-02-21 17:20 ? 次閱讀

你是否對 MySQL 數據庫中的事務已經有所了解?看下面這張圖,按照 1~6 的順序依次執行,在RR隔離級別下,事務 A 和事務 B 各自輸出的 num 值是多少嗎?

b321a948-a8d8-11ed-bfe3-dac502259ad0.png

我們預先創建好這樣一張表并初始化一條數據:

CREATETABLE`test1`(
`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'主鍵Id',
`num`int(11)NULLCOMMENT'數量',
PRIMARYKEY(`id`)
)ENGINE=InnoDB;

insertintotest1(id,num)values(1,1);

然后開始按上圖的順序執行各個事務,這需要我們打開3個操作窗口來分別執行 A、B、C 三個事務:

事務 A:

b33938ba-a8d8-11ed-bfe3-dac502259ad0.png

事務 B:

b34dae80-a8d8-11ed-bfe3-dac502259ad0.png

事務 C:

b36bd004-a8d8-11ed-bfe3-dac502259ad0.png

按照上圖的執行順序執行 commit,其中事務 C 是自動提交事務的,不需要我們顯示的 commit,事務 A、B 的輸出結果如下:

事務A:num=1

事務B:num=3

為什么是這樣輸出?

它的背后其實是:MVCC(多版本并發控制)、consistent read(一致性讀)、locking reads(鎖定讀)等 MySQL 數據庫底層知識。

1、MVCC

MySQL 數據庫官網文檔是這樣來描述 MVCC 的:

b3863796-a8d8-11ed-bfe3-dac502259ad0.png

多版本控制: 指的是一種提高并發的技術。最早的數據庫系統,只有讀讀之間可以并發,讀寫,寫讀,寫寫都要阻塞。引入多版本之后,只有寫寫之間相互阻塞,其他三種操作都可以并行,這樣大幅度提高了 InnoDB 的并發度。在內部實現中,與 Postgres 在數據行上實現多版本不同,InnoDB 是在 undolog 中實現的,通過 undolog 可以找回數據的歷史版本。

找回的數據歷史版本可以提供給用戶讀(按照隔離級別的定義,有些讀請求只能看到比較老的數據版本),也可以在回滾的時候覆蓋數據頁上的數據。在 InnoDB 內部中,會記錄一個全局的活躍讀寫事務數組,其主要用來判斷事務的可見性。

目前來看 MVCC 的實現依賴于:

隱藏字段(DB_TRX_ID、DB_ROLL_PTR)

回滾日志(undo log)

一致性讀(consistent read)

你也可以這樣去理解 MVCC:一個事務對數據進行更新操作時候,先把舊的數據放到一個單獨的地方(回滾段),其他事務讀取數據時候,根據 DB_TRX_ID、DB_ROLL_PTR 計算出 undo log 鏈中當前版本的數據。

2、一致性讀(consistent read)

繼續看官方文檔對 consistent read 的描述:

b3bab3f4-a8d8-11ed-bfe3-dac502259ad0.png

直譯:

一個讀操作使用基于某個時刻的快照信息來顯示查詢結果,而不考慮同時運行的其他事務所執行的更改。如果查詢到的數據被其他事務所更改,則根據 undo log 中的內容來重建原始數據。這種技術避免了一些通過強制事務等待其他事務完成而降低并發性的鎖定問題。

在 RR 級別下,首次讀操作被執行時候創建一致性讀視圖 ReadView,事務的后續讀都基于該視圖的數據;

在 RC 級別下,每一次讀操作都會創建一個最新的 ReadView,因此每次 select 讀都可以獲取到當前已提交事務的最新數據。

“一致性讀”是 InnoDB 引擎在 RC 和 RR 隔離級別下處理 select 語句的默認模式。因為一個“一致性讀”是不需要對它訪問的表設置任何的鎖,當對表執行“一致性讀”時候,其他會話可以自由的修改這些表。

另外:

讀未提交(read uncommitted)、串行化(serializable)是不需要依賴 MVCC 的,讀未提交直接每次都讀取當前數據的最新值即可。而 serializable 是直接采用加鎖的操作讓所有的事務都串行化執行,犧牲了并發能力。

一致性讀的實現方式:

每個事務啟動的瞬間,都會構建一個數組(m_ids),用來記錄目前所有“活躍事務”(事務啟動了,但是還沒提交)的 ID;

數組中的最小事務 ID 為低水位;

數組中的最大事務 ID + 1 為高水位;

數據版本可見性規則:當前數據某個版本是否可見,取決于當前數據的 DB_TRX_ID 以及這個一致性視圖數組中記錄的事務 ID 做對比來判斷:低水位以前的數據版本可見,高水位以后的數據版本不可見,低水位和高水位之間得查看當前數據版本的 DB_TRX_ID 是否存在數組中,若存在意味著事務未提交,不可見,若不存在意味著事務已提交,可見。

b3fa8894-a8d8-11ed-bfe3-dac502259ad0.png

那按照一致性讀的理解,事務B已經創建了自己的快照數據了,它的輸出應該是 num = 2 呀,為什么會是 num=3?

可是如果不是 num=3,那么已經提交的事務 C 的操作不就丟失了嗎?(產生丟失更新問題)

這里又涉及到一個知識點:

更新數據都是先讀后寫的,而這個讀,只能讀當前的值,稱為“當前讀”(current read)。

3、當前讀(current reads)

也叫做鎖定讀(locking reads)

b40abc00-a8d8-11ed-bfe3-dac502259ad0.png

InnoDB 引擎支持兩種方式的鎖定讀以提供額外的安全性(MySQL 5.7 版本):

#讀鎖(S鎖,共享鎖)
SELECT...LOCKINSHAREMODE;
#寫鎖(X鎖,排他鎖)
SELECT...FORUPDATE;

鎖定讀會在被讀取的數據上加一把共享鎖,其他事務可以讀取記錄,但是不可以修改記錄,直到當前事務提交。

鎖定讀驗證:

b4225c70-a8d8-11ed-bfe3-dac502259ad0.png

為什么要有鎖定讀?

如果你在一個事務中先查詢了一個數據,然后插入或者更新相關的數據,這個時候來了一個事務B同時更新或者刪除你要查詢的記錄,就會出現幻讀問題了。

這也是為什么 MVCC 不能完全解決幻讀的問題,而是需要 MVCC + 行鎖 + 間隙鎖(next-key lock)的方式。

4、事務 A、B、C 的執行流程

繼續看開頭的第一張圖:

b321a948-a8d8-11ed-bfe3-dac502259ad0.png

starttransactionwithconsistentsnapshot;

這條 SQL 語句可以立即啟動事務,創建當前事務的一致性讀快照。效果等同于 start transaction 然后馬上執行 select 語句。

我們接下來看看文章開頭的三個事務對數據行的修改流程,按照步驟 1~6 的操作如下:

b4551890-a8d8-11ed-bfe3-dac502259ad0.png

如果大家細致的查看上圖的三個事務的穿插執行流程,可以發現,A、B、C 三個事務無論是 commit 還是 rollback,都是可以最終得到正確的數據。

這就是 InnoDB 引擎下的多版本并發控制(MVCC)的實現原理。

總結以下幾個關鍵點:

每一個事務都會創建一個數據快照,快照創建的時機根據隔離級別的不同有所區別;

每一個事務都會生成一個全局唯一的 DB_TRX_ID,用于標記當前版本;

DB_ROLL_PTR 是回滾指針的意思,結合 DB_TRX_ID 來最終確定我要拿到的數據;

DB_TRX_ID、DB_ROLL_PTR、undo log 這三個值來控制數據的版本;

update、delete 操作都是先讀后寫,這個讀屬于鎖定讀(當前讀)。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • TRX
    TRX
    +關注

    關注

    0

    文章

    3

    瀏覽量

    9229
  • MySQL
    +關注

    關注

    1

    文章

    826

    瀏覽量

    26666
  • MYSQL數據庫
    +關注

    關注

    0

    文章

    96

    瀏覽量

    9419
  • MVCC
    +關注

    關注

    0

    文章

    13

    瀏覽量

    1481

原文標題:MySQL 底層之 MVCC、回滾段、一致性讀、鎖定讀

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何在Rust連接和使用MySQL數據庫

    如何在Rust連接和使用MySQL數據庫。 安裝 mysql 模塊 這里我們假設已經安裝了R
    的頭像 發表于 09-30 17:05 ?1734次閱讀

    labview連接mysql數據庫的問題

    這個ODBC數據已經成功設置了,為什么用labview連接mysql數據庫就出現這個錯誤?望大神解答,謝謝啦!
    發表于 08-19 08:30

    詳解Mysql數據庫InnoDB存儲引擎事務

    關于Mysql數據庫InnoDB存儲引擎事務的一點理解
    發表于 05-13 10:11

    什么是MySQL數據庫?ASPNET和MySQL數據庫的入門簡介

    在ASP時代,如果我們要建立一個數據庫驅動的web站點,那么可以選擇環很多錢的微軟SQL SERVER數據庫或者選擇要花很多時間來尋找達到性能和穩定性統一的ACCESS數據庫,但在.
    發表于 11-22 16:20 ?4次下載

    MySQL數據庫如何安裝和使用說明

    MySQL數據庫開發 基礎概念 1.數據:描述事物特征的符號,屬性 2.數據庫的概念:管理計算機
    的頭像 發表于 02-13 16:13 ?2826次閱讀

    Mysql和Oracle數據庫之間的誤區

    Mysql 和Oracle 在開發的使用是隨處可見的,那就簡單去了解一下這倆款火的不行的數據庫。 本質區別: Oracle數據庫是一個對象
    的頭像 發表于 11-13 09:35 ?1950次閱讀
    <b class='flag-5'>Mysql</b>和Oracle<b class='flag-5'>數據庫</b>之間的誤區

    華為云數據庫-RDS for MySQL數據庫

    (for MySQL)為輔。 MySQL數據庫是全球最受歡迎的一種數據庫,它是屬于 Oracle旗下的一款產品,MySQL是一種關系型
    的頭像 發表于 10-27 11:06 ?1557次閱讀

    有哪些不同的MySQL數據庫引擎?

    數據庫引擎是MySQL組件,可以處理SQL操作,例如從數據庫創建、讀取和更新數據MySQL中有兩種類型的引擎:
    的頭像 發表于 04-03 16:38 ?1165次閱讀

    GaussDB數據庫事務介紹

    之一,因此事務管理在數據庫技術占據了極為重要的位置。在這里我們將著重介紹華為云數據庫 GaussDB 對事務的支持及管理,包括
    的頭像 發表于 06-05 16:28 ?924次閱讀
    GaussDB<b class='flag-5'>數據庫</b><b class='flag-5'>事務</b>介紹

    MySQL數據庫管理與應用

    討論MySQL數據庫的管理和應用。 管理MySQL數據庫 在管理MySQL數據庫之前,我們需要
    的頭像 發表于 08-28 17:15 ?1009次閱讀

    MySQL數據庫基礎知識

    的基礎知識,包括其架構、數據類型、表操作、查詢語句和數據導入導出等方面。 MySQL 數據庫架構 MySQL
    的頭像 發表于 11-21 11:09 ?1003次閱讀

    mysql數據庫基礎命令

    MySQL是一個流行的關系型數據庫管理系統,經常用于存儲、管理和操作數據。在本文中,我們將詳細介紹MySQL的基礎命令,并提供與每個命令相關的詳細解釋。 登錄
    的頭像 發表于 12-06 10:56 ?616次閱讀

    eclipse怎么連接數據庫mysql

    連接Eclipse和MySQL數據庫可以通過JDBC(Java Database Connectivity)來實現。以下是詳細步驟: 下載并安裝MySQL數據庫
    的頭像 發表于 12-06 11:06 ?1342次閱讀

    數據庫數據恢復—Mysql數據庫表記錄丟失的數據恢復流程

    Mysql數據庫故障: Mysql數據庫表記錄丟失。 Mysql數據庫故障表現: 1、
    的頭像 發表于 12-16 11:05 ?203次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b>恢復—<b class='flag-5'>Mysql</b><b class='flag-5'>數據庫</b>表記錄丟失的<b class='flag-5'>數據</b>恢復流程

    MySQL數據庫的安裝

    MySQL數據庫的安裝 【一】各種數據庫的端口 MySQL :3306 Redis :6379 MongoDB :27017 Django :8000 flask :5000 【二】
    的頭像 發表于 01-14 11:25 ?108次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>數據庫</b>的安裝
    主站蜘蛛池模板: 天天玩天天干| 五月天婷婷网站| 久久青草精品免费资源站| 欧美乱码视频| 六月综合| 成人免费观看一区二区| 伊人狼人综合网| 天天操天天干天天舔| 国产午夜免费| 黄视频网站入口| 深夜动态福利gif进出粗暴| xxxxxx性| 色婷婷精品视频| 欧美日a| 韩国三级无遮挡床戏视频| bt磁力在线搜索| 天天干天天透| se色成人亚洲综合| 特黄特色大片免费播放路01| 亚洲人免费视频| 日本三级香港三级人妇99| 国产在线视频你懂得| 午夜看片在线观看| 高清午夜毛片| 精品国产自在现线看久久| 天天操丝袜| 看真人一级毛多毛片| 91噜噜噜| 超碰v| 高h文男主又粗又狠| 四虎在线影院| 狠狠狠色丁香婷婷综合久久88| 天天爽夜夜爽视频| 最新黄色在线| 中日韩黄色大片| 欧美性天堂| 亚洲午夜精品在线| 午夜视频啪啪| 5060午夜一级| 美女拍拍拍黄色| 天天色综合社区|