【高并發(fā)基礎(chǔ)】理解MVCC及提煉實(shí)現(xiàn)思想-創(chuàng)新互聯(lián)

文章目錄
    • 1. 前言
    • 2. MVCC 概念
      • 2.1 MVCC 版本鏈
      • 2.2 MVCC trx_id
      • 2.3 MVCC Read View
    • 3. 提出問題
    • 4. 解決問題
      • 4.1 不讀未提交的數(shù)據(jù)
        • 4.1.1 一般的并發(fā)情況
        • 4.1.2 特殊的并發(fā)情況
        • 4.1.3 剩下的并發(fā)情況
      • 4.2 如果自己修改了數(shù)據(jù),要第一時(shí)間讀到
    • 5. MySQL RC 使用 MVCC
      • 5.1 MVCC DML 會(huì)生成新的 Read View 嗎?
      • 5.2 MySQL RC 建立 Read View 的時(shí)機(jī)
    • 6. MySQL RR 使用 MVCC
      • 6.1 MySQL RR 建立 Read View 的時(shí)機(jī)
    • 7. 提煉 MVCC 的思想
    • 8. 后記

成都創(chuàng)新互聯(lián)公司于2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元涇縣做網(wǎng)站,已為上家服務(wù),為涇縣各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:189820811081. 前言

MVCC 在 MySQL、Oracle、PostgreSQL 都有應(yīng)用,用于實(shí)現(xiàn)事務(wù)的隔離特性?,F(xiàn)在結(jié)合 《MySQL是怎樣運(yùn)行的》的內(nèi)容理解、歸納、整理下MVCC的實(shí)現(xiàn)及思想。

2. MVCC 概念

Multiversion Concurrency Control 對(duì)版本并發(fā)控制。
對(duì)于同一行數(shù)據(jù),會(huì)根據(jù)不同事務(wù)的DML操作參生不同的版本,讓不同事務(wù)各自維護(hù)自己能看到的版本從而做到事務(wù)隔離。

2.1 MVCC 版本鏈

每次操作數(shù)據(jù)庫都會(huì)生成日志,那么就可以把同一條記錄的多次操作記錄按時(shí)間順序鏈接起來。
在這里插入圖片描述

以上圖片參考博客

2.2 MVCC trx_id

按事務(wù)開啟的時(shí)間順序,為事務(wù)頒發(fā)一個(gè)Id,從而維護(hù)“版本”。是討論MVCC實(shí)現(xiàn)的基礎(chǔ)。

2.3 MVCC Read View

光有日志記錄還不夠,每個(gè)事務(wù)應(yīng)該要維護(hù)自己的 “視野范圍”。也就是當(dāng)前事務(wù)到底能看到什么版本的數(shù)據(jù),建立 Read View,并與版本鏈協(xié)作,就能約束事務(wù)的視野,從而實(shí)現(xiàn)隔離。
Read View 包含:

  1. m_ids
  2. min_trx_id
  3. max_trx_id
  4. creator_trx_id

Read View 里面有多個(gè)屬性,他們是分別用于解決不同問題的。如果一上來就把四個(gè)都搞懂,容易暈。

3. 提出問題

這個(gè)事務(wù)隔離方案需要回答以下問題:

  • 如何控制當(dāng)前事務(wù)讀不到其他事務(wù) 未提交 的數(shù)據(jù)
  • 如果自己事務(wù)修改了數(shù)據(jù),怎么第一時(shí)間讀到

回答以上問題后,也順帶把MySQLRCRR使用MVCC的原理給理解了

4. 解決問題

我們把日志的 trx_id 與 區(qū)間 [min_trx_id, max_trx_id ] 的命中關(guān)系羅列出來,用于后續(xù)討論問題

trx_id >= Read View. max_trx_id
Read View. max_trx_id  >trx_id  >=  Read View. min_trx_id
trx_id< Read View. min_trx_id

值得一提的是,

trx_id == Read View. creator_trx_id

不在區(qū)間討論范圍,屬于前置判斷(這個(gè)條件滿足了,就不看區(qū)間命中情況了)

4.1 不讀未提交的數(shù)據(jù) 4.1.1 一般的并發(fā)情況

新引入以下參數(shù):

  • max_trx_id:這個(gè)屬性容易搞混,它表示系統(tǒng)應(yīng)該分配給下一個(gè)事務(wù)的食物Id
    • 即若 creator_trx_id = 3,max_trx_id 一定 >3

事務(wù)生成了 Read View 之后,對(duì)數(shù)據(jù)行進(jìn)行讀取,發(fā)現(xiàn)日志中有

trx_id >= Read View. max_trx_id

則說明該日志發(fā)生在建立 Read View 之后,并且生成該日志的事務(wù)是在當(dāng)前事務(wù)之后開啟。
至此,我們能夠得到一個(gè)信息:該日志發(fā)生在當(dāng)前事務(wù)開啟之后,可能是還未提交的事務(wù)
那么,爭(zhēng)取不讀未提交的事務(wù),只用做一件事:忽略該日志


4.1.2 特殊的并發(fā)情況

新引入兩個(gè)參數(shù)

  • min_trx_id: 當(dāng)前所有事務(wù)中,活躍的(未提交的)事務(wù)中 trx_id 最小的一個(gè)
  • m_ids: 當(dāng)前所有事務(wù)中,活躍的(未提交的)事務(wù)列表

事務(wù)生成了 Read View 之后,對(duì)數(shù)據(jù)行進(jìn)行讀取,發(fā)現(xiàn)日志中有

Read View. max_trx_id  >trx_id  >=  Read View. min_trx_id

則說明該日志發(fā)生在建立 Read View 之后,并且生成該日志的事務(wù)是在當(dāng)前事務(wù)之后開啟。
對(duì)比上文的"一般的情況",max_trx_id指系統(tǒng)下一個(gè)要建立的事務(wù)Id,若存在以下關(guān)系:

Read View. max_trx_id  >trx_id

說明該日志的事務(wù)跟建立 Read View 的時(shí)機(jī)挨得很近,我們還是可以考慮一下這條日志。具體怎么考慮呢?
m_ids 在 Read View 中負(fù)責(zé)記錄建立 Read View 那一刻的 活躍事務(wù)。
如果日志中的 trx_id 不在活躍事務(wù)列表,側(cè)面說明該日志的事務(wù)已經(jīng)提交,則可以讀取它。


4.1.3 剩下的并發(fā)情況
trx_id< Read View. min_trx_id

這個(gè)比較簡(jiǎn)單,直接讀即可。由于較新的日志一定會(huì)置頂,讀到 trx_id< Read View. min_trx_id 立馬返回?cái)?shù)據(jù)即可。


4.2 如果自己修改了數(shù)據(jù),要第一時(shí)間讀到

引入以下參數(shù)

  • creator_trx_id: Read View 中事務(wù)的DML操作會(huì)觸發(fā)建立 trx_id (事務(wù)id)
trx_id == Read View. creator_trx_id

該日志是當(dāng)前事務(wù)的最新語句創(chuàng)建的,直接讀取即可。該判斷放在了區(qū)間命中討論之前,所以一定會(huì)先讀到自己更新的數(shù)據(jù)。
如果開啟一個(gè)事務(wù),該事務(wù)一直沒有DML操作,creator_trx_id = 0,即永遠(yuǎn)不會(huì)出現(xiàn)

trx_id == Read View. creator_trx_id
5. MySQL RC 使用 MVCC

MySQL 會(huì)對(duì)每個(gè)查詢語句生成 Read View。

5.1 MVCC DML 會(huì)生成新的 Read View 嗎?

并不會(huì),DML語句操作語句交給鎖處理了,MVCC只是控制讀取的數(shù)據(jù)的版本。
那么DML跟Read View無關(guān)嗎,當(dāng)然也不是,上文交代,使用 creator_trx_id 登記自己操作了的數(shù)據(jù)。

5.2 MySQL RC 建立 Read View 的時(shí)機(jī)

每個(gè)讀取操作都會(huì)建立一個(gè)新的 Read View, 所以存在不可重復(fù)讀的并發(fā)隱患。

6. MySQL RR 使用 MVCC

RR 的隔離級(jí)別比 RC 高,其中隔離性的提高本質(zhì)上就是調(diào)整了 Read View 創(chuàng)建的時(shí)機(jī)

6.1 MySQL RR 建立 Read View 的時(shí)機(jī)

第一個(gè)查詢語句生成 Read View,后續(xù)的所有查詢都 復(fù)用這個(gè) Read View,所以每次讀取的值,都來源于同一個(gè)版本。

7. 提煉 MVCC 的思想

MVCC 在保持隔離性的前提下,盡大努力去讀最新的數(shù)據(jù)。它不會(huì)立即判斷數(shù)據(jù)是未提交的,而是記錄下建立 Read View 那一剎那的事務(wù)并發(fā)情況,交由一套算法去甄別。

  • 懷疑日志是未提交的數(shù)據(jù)

    • 自己DML操作的數(shù)據(jù)
      • 由 creator_trx_id 跟進(jìn)記錄并讀取
    • 其他事務(wù)DML操作的數(shù)據(jù)
      • 由 trx_id 與 區(qū)間 [min_trx_id, max_trx_id ] 的命中關(guān)系確認(rèn)為已提交數(shù)據(jù)則讀取
  • 確認(rèn)日志是已提交的數(shù)據(jù)

    • 讀最新的版本

上文說的日志,是因?yàn)槿罩境休d的是一個(gè)思想,MySQL是用 undo log支撐MVCC的,而PostgreSQl則不是。

8. 后記

早期寫的 InnoDB 如何避免臟讀和不可重復(fù)讀,是不嚴(yán)謹(jǐn)?shù)牡胤?,現(xiàn)在糾正過來,希望持續(xù)學(xué)習(xí),不斷進(jìn)步。
MVCC 給我的啟示是,我們可以嘗試用區(qū)間命中的思想去分解問題,當(dāng)命中關(guān)系被完全覆蓋,我們可以認(rèn)為問題被分解完成。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站題目:【高并發(fā)基礎(chǔ)】理解MVCC及提煉實(shí)現(xiàn)思想-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://muchs.cn/article46/cdsseg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、網(wǎng)站排名、關(guān)鍵詞優(yōu)化、外貿(mào)建站、網(wǎng)站設(shè)計(jì)公司、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)