中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)規(guī)范搜狗搜索引擎推廣

網(wǎng)站建設(shè)規(guī)范,搜狗搜索引擎推廣,南京美容網(wǎng)站建設(shè),建設(shè)制作網(wǎng)站一、前言 在分析 MVCC 的原理之前,我們先回顧一下 MySQL 的一些內(nèi)容以及關(guān)于 MVCC 的一些簡單介紹。(注:下面沒有特別說明默認(rèn) MySQL 的引擎為 InnoDB ) 1.1 數(shù)據(jù)庫的并發(fā)場景 數(shù)據(jù)庫并發(fā)場景有三種,分別是: 讀-讀…


一、前言

在分析 MVCC 的原理之前,我們先回顧一下 MySQL 的一些內(nèi)容以及關(guān)于 MVCC 的一些簡單介紹。(注:下面沒有特別說明默認(rèn) MySQL 的引擎為 InnoDB )

1.1 數(shù)據(jù)庫的并發(fā)場景

數(shù)據(jù)庫并發(fā)場景有三種,分別是:

  • 讀-讀:不存在線程安全問題,不需要并發(fā)控制。
  • 讀-寫:有線程安全問題,可能會(huì)造成事務(wù)隔離性問題,可能遇到臟讀、不可重復(fù)讀、幻讀等問題。
  • 寫-寫:有線程安全問題,可能會(huì)存在更新丟失的問題,比如第一類更新丟失、第二類更新丟失。

(第一類丟失更新:事務(wù)A回滾時(shí),將已經(jīng)提交的事務(wù)B的更新數(shù)據(jù)覆蓋了;第二類丟失更新:事務(wù)A提交覆蓋了事務(wù)B已經(jīng)提交的數(shù)據(jù),造成事務(wù)B所做的操作丟失)

1.2 什么是 MVCC

  • MVCC全稱 Multi-Version Concurrency Control ,即多版本并發(fā)控制,MVCC 是一種并發(fā)控制的方法,一般在數(shù)據(jù)庫管理系統(tǒng)中實(shí)現(xiàn)對數(shù)據(jù)庫的并發(fā)訪問,在編程語言中實(shí)現(xiàn)事務(wù)內(nèi)存。
  • 多版本控制:指的是一種提高并發(fā)的技術(shù),在最早的數(shù)據(jù)庫系統(tǒng)中只有讀-讀之間可以并發(fā),讀-寫、寫-寫之間都要阻塞。引入多版本并發(fā)控制之后,只有寫-寫之間相互阻塞,其他三種操作都可以并行,這樣大幅的提高了 InnoDB 的并發(fā)度。在內(nèi)部實(shí)現(xiàn)中,InnoDB 是通過 undo log 實(shí)現(xiàn)的,通過 undo log 可以找回?cái)?shù)據(jù)的歷史版本。找回的歷史版本可以提供給用戶讀(按照隔離級別的定義,有些讀請求只能看到比較老的數(shù)據(jù)版本),也可以在回滾的時(shí)候覆蓋數(shù)據(jù)頁上的數(shù)據(jù)。在 InnoDB 內(nèi)部中,會(huì)記錄一個(gè)全局的活躍讀寫事務(wù)數(shù)組,其主要用來判斷事務(wù)的可見行。

一句話概述,MVCC 在 MySQL InnoDB 中的實(shí)現(xiàn)主要是為了提高數(shù)據(jù)庫并發(fā)性能,用更好的方式去處理讀寫沖突,做到即使有讀寫沖突時(shí),也能做到不加鎖,做到非阻塞并發(fā)讀

1.3 當(dāng)前讀和快照讀

  • 當(dāng)前讀

    select xxx lock in share mode; # 共享鎖

    #排它鎖
    select xxx for update;
    update xxx;
    delete xxx;
    insert xxx;

    像上面的這些操作就是一種當(dāng)前讀,因?yàn)樗x取的是數(shù)據(jù)的最新版本,讀取時(shí)還要保證其他事務(wù)不能修改當(dāng)前記錄,會(huì)對記錄進(jìn)行加鎖。

  • 快照讀

    不加鎖的 select 就是快照讀,即不加鎖的非阻塞讀。(快照讀的前提是隔離級別不是 serializable,serializable 的隔離級別下快照讀會(huì)退化成當(dāng)前讀) 之所以出現(xiàn)快照讀的情況,是基于提高并發(fā)性能的考慮,快照讀的實(shí)現(xiàn)是基于 MVCC 的,可以認(rèn)為 MVCC 是行鎖的一個(gè)變種,但是它在很多情況下避免了加鎖操作,降低了開銷。既然是基于多版本,所以快照讀可能讀到的不一定是數(shù)據(jù)的最新版本,而有可能是之前的歷史版本。

1.4 當(dāng)前讀和快照讀與 MVCC 的關(guān)系

準(zhǔn)確的說,MVCC 指的是**"維護(hù)一個(gè)數(shù)據(jù)的多個(gè)版本,使得讀寫操作沒有沖突"這么一個(gè)概念,僅僅是一個(gè)理想狀態(tài)。而在 MySQL 中,實(shí)現(xiàn)這么一個(gè) MVCC 理想概念,我們就需要 MySQL 提供具體的功能去實(shí)現(xiàn),而快照讀**就是 MySQL 為我們實(shí)現(xiàn) MVCC 理想模型的其中一個(gè)具體非阻塞讀功能。而相對而言,當(dāng)前讀就是一個(gè)悲觀鎖的具體功能實(shí)現(xiàn),而要說的在細(xì)致一點(diǎn),快照讀本身也是一個(gè)抽象概念,在深入研究,MVCC 模型在 MySQL 中的具體實(shí)現(xiàn)則是由三個(gè)隱式字段、undo log 、Read View 等去完成的。

1.5 MVCC 能解決什么問題

MVCC 是一種解決讀寫沖突的無鎖并發(fā)控制手段,也就是為事務(wù)分配單向增長的時(shí)間戳,為每個(gè)修改保存一個(gè)版本,版本與事務(wù)時(shí)間戳關(guān)聯(lián),讀操作只讀該事務(wù)開始前的數(shù)據(jù)庫的快照,所以 MVCC 可以為數(shù)據(jù)庫解決以下問題:

  1. 在并發(fā)讀數(shù)據(jù)庫時(shí),可以做到在讀操作時(shí)不用阻塞寫操作,寫操作也不用阻塞讀操作,提高了數(shù)據(jù)庫并發(fā)讀寫性能。
  2. 可以解決臟讀、不可重復(fù)讀、幻讀等事務(wù)隔離問題(不能解決更新丟失的問題)。

所以說 MVCC 就是開發(fā)人員不滿意只讓數(shù)據(jù)庫采用悲觀鎖(加鎖)這樣性能不佳的形式去解決讀-寫的問題而提出的解決方案,所以在數(shù)據(jù)庫中,因?yàn)橛辛?MVCC ,所以我們可以形成兩個(gè)組合:

  1. MVCC + 悲觀鎖

MVCC解決讀寫沖突,悲觀鎖解決寫-寫沖突

  1. MVCC + 樂觀鎖

MVCC解決讀寫沖突,樂觀鎖解決寫-寫沖突。

二、MVCC實(shí)現(xiàn)原理

2.1 隱式字段

在一張表中,除了我們自定義的字段,實(shí)際上 MySQL 會(huì)隱式的定義一些字段。

  • DB_TRX_ID

    6byte,最近修改(修改/插入)事務(wù)ID:記錄創(chuàng)建這條記錄/最后一次修改該記錄的事務(wù)ID

  • DB_ROLL_PTR

    7byte,回滾指針,指向這條記錄的上一個(gè)版本(存儲于 rollback segment 里)

  • DB_ROW_ID

    6byte,隱含的自增ID(隱藏主鍵),如果數(shù)據(jù)表沒有主鍵,InnoDB 會(huì)自動(dòng)以 DB_ROW_ID 產(chǎn)生一個(gè)聚簇索引

  • 實(shí)際還有一個(gè)刪除 flag 隱藏字段, 即記錄被更新或刪除并不代表真的刪除,而是刪除 flag 變了

例如下面是 person 表的某條記錄,如下圖,DB_ROW_ID 是數(shù)據(jù)庫為改行記錄生產(chǎn)的唯一隱式主鍵,DB_TRX_ID 是當(dāng)前操作該記錄的事務(wù)ID,而 DB_ROLL_PTR 是一個(gè)回滾指針,用于配合 undo log 日志,指向上一個(gè)版本。

59c8504fac0e965a699bd647b86a2075.jpeg

2.2 undo log日志

undo log 類型

  • insert undo log

    是指在 insert 操作中產(chǎn)生的 undo log。因?yàn)?amp;nbsp;insert 操作的記錄,只對當(dāng)前事務(wù)本身可見,對其他事務(wù)不可見(這是事務(wù)隔離性的要求),因此這種 undo log 可以在事務(wù)提交后直接刪除。不需要進(jìn)行 purge 操作

  • update undo log

    是對 delete 和 update 操作產(chǎn)生的 undo log。該 undo log 可能需要提供給 MVCC 機(jī)制使用,因此不能在事務(wù)提交時(shí)就進(jìn)行刪除,提交時(shí)放入 undo log 鏈表,等待 purge 線程進(jìn)行最后的刪除。

 

purge 線程

為了實(shí)現(xiàn) InnoDB 的 MVCC 機(jī)制,更新或者刪除操作都只是設(shè)置一下老記錄的 deleted_bit(即前面提到的刪除 flag ),并不真正將過時(shí)的記錄刪除。為了節(jié)省磁盤空間,InnoDB 有專門的 purge 線程來清理 deleted_bit 為 true 的記錄。為了不影響 MVCC 的正常工作,purge 線程自己也維護(hù)了一個(gè) Read View(這個(gè) Read View 相當(dāng)于系統(tǒng)中最老活躍事務(wù)的 Read View ),如果某個(gè)記錄的 deleted_bit 為true,并且 DB_TRX_ID 相對于 purge 線程的 Read View 可見,那么這條記錄一定是可以被安全清除的。

 

對 MVCC 有幫助的實(shí)質(zhì)是 update undo log ,undo log 存在于 rollback segment 中舊記錄鏈,它的執(zhí)行流程如下:

  1. 一個(gè)事務(wù)插入 person 表插入了一條新記錄,記錄如下,name 為 Jerry, age 為24,隱式主鍵是1,事務(wù)ID和回滾指針我們假設(shè)為NULL。
c6833cc0c414d33f0a96a06ae82ec1aa.jpeg

2.現(xiàn)在來了一個(gè) 事務(wù)1 對記錄的 name 進(jìn)行了修改,改為了 Tom,執(zhí)行過程如下:

  1. 在事務(wù)1修改該行數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)先對這行記錄加排它鎖。
  2. 然后把該行數(shù)據(jù)拷貝到 undo log 中,作為舊記錄,即在 undo log 中有當(dāng)前行的拷貝副本。
  3. 拷貝完畢后,修改該行的 name 為 tom,并且修改隱藏字段的事務(wù)ID為當(dāng)前事務(wù)1的ID,我們默認(rèn)從1開始,之后遞增,回滾指針指向拷貝到 undo log 的副本記錄,即表示我的上一個(gè)版本就是它。
  4. 事務(wù)提交后,釋放排它鎖。
bc40d092725fe55a9ce79ee5938e7d41.jpeg

3.又來了個(gè)事務(wù)2修改 person 表的同一個(gè)記錄,將 age 修改為30歲,執(zhí)行過程如下:

  1. 在事務(wù)2修改該行數(shù)據(jù)時(shí),數(shù)據(jù)庫也先為該行加鎖
  2. 然后把該行數(shù)據(jù)拷貝到 undo log 中,作為舊記錄,發(fā)現(xiàn)該行記錄已經(jīng)有 undo log 了,那么最新的舊數(shù)據(jù)作為鏈表的表頭,插在該行記錄的 undo log 最前面
  3. 修改該行 age 為30歲,并且修改隱藏字段的事務(wù)ID為當(dāng)前事務(wù)2的ID, 那就是2,回滾指針指向剛剛拷貝到 undo log 的副本記錄
  4. 事務(wù)提交,釋放鎖
646692e22d5bf072645d4393db1ce22c.jpeg

從上面我們可以看出,不同事務(wù)或者相同事務(wù)對同一記錄的修改,會(huì)導(dǎo)致該記錄的 undo log 稱為一條記錄版本線性表,即鏈表,undo log 的表頭就是最新的舊記錄,(當(dāng)然就像之前說的該 undo log 的節(jié)點(diǎn)可能會(huì)被 purge 線程清除掉,像圖中的第一條 insert undo log ,其實(shí)在事務(wù)提交之后可能就被刪除丟失了,不過這里為了演示,所以還放在這里)

2.3 Read View

 

什么是 Read View ?

Read View 是事務(wù)進(jìn)行快照讀操作時(shí)產(chǎn)生的讀視圖,在該事務(wù)執(zhí)行快照讀的那一刻,會(huì)生成數(shù)據(jù)庫系統(tǒng)的當(dāng)前的一個(gè)快照,記錄并維護(hù)當(dāng)前活躍事務(wù)的ID(當(dāng)每個(gè)事務(wù)開啟時(shí),都會(huì)被分配一個(gè) ID,這個(gè) ID 是自增的,所以最新的事務(wù),ID 值越大)

 

可見行判斷

所以我們知道 Read View 主要是用來做可見性判斷的,即當(dāng)我們某個(gè)事務(wù)執(zhí)行快照讀的時(shí)候,對該記錄創(chuàng)建一個(gè) Read View 讀視圖,把它比作條件來判斷當(dāng)前事務(wù)能夠看到哪個(gè)版本的數(shù)據(jù),既可能是當(dāng)前最新的數(shù)據(jù),也有可能是該行記錄的 undo log 里面的某個(gè)版本的數(shù)據(jù)。

Read View 遵循一個(gè)可見性算法,主要是將要被修改的數(shù)據(jù)的最新記錄的 DB_TRX_ID(即當(dāng)前事務(wù)ID),與系統(tǒng)當(dāng)前其他活躍事務(wù)的ID去對比(由 Read View 維護(hù)),如果 DB_TRX_ID 跟 Read View 的屬性做了某些對比,不符合可見性,那么就由 DB_ROLL_PTR 回滾指針去取出undo log中的 DB_TRX_ID 再比較,即遍歷鏈表的 DB_TRX_ID(從鏈表頭到尾,即從最近的一次修改查起),直到找到滿足特定條件的 DB_TRX_ID,那么這個(gè) DB_TRX_ID 所在的舊記錄就是當(dāng)前事務(wù)能看見的最新的老版本。

 

判斷條件是什么?

我們可以將 Read View 簡單的理解為三個(gè)全局屬性

  • trx_list 一個(gè)數(shù)值列表,用來維護(hù) Read View 生成時(shí)刻此時(shí)系統(tǒng)正活躍的事務(wù)ID

  • up_limit_id 記錄 trx_list 中的最小的事務(wù) ID

  • low_limit_id 在 Read View 生成時(shí)刻系統(tǒng)尚未分配的下一個(gè)事務(wù) ID,即目前(不一定是 Read View 中)已經(jīng)出現(xiàn)過的事務(wù) ID 最大值+1

     

    比較步驟

  1. 首先比較 DB_TRX_ID < up_limit_id, 如果小于,則當(dāng)前事務(wù)能看到 DB_TRX_ID 所在的記錄,如果大于等于進(jìn)入下一個(gè)判斷。
  2. 接下來判斷 DB_TRX_ID 大于等于 low_limit_id , 如果大于等于則代表 DB_TRX_ID 所在的記錄在 Read View 生成后才出現(xiàn)的,那對當(dāng)前事務(wù)肯定不可見,如果小于則進(jìn)入下一個(gè)判斷。
  3. 判斷 DB_TRX_ID 是否在活躍事務(wù)之中,trx_list.contains( DB_TRX_ID ),如果在,則代表我 Read View 生成時(shí)刻,你這個(gè)事務(wù)還在活躍,還沒有 Commit,你修改的數(shù)據(jù),我當(dāng)前事務(wù)也是看不見的;如果不在,則說明,你的這個(gè)事務(wù)在 Read View 生成之前就已經(jīng) Commit了,你修改的結(jié)果,我當(dāng)前事務(wù)是能看見的。

2.4 實(shí)現(xiàn)流程

我們在了解了隱式字段、undo log 以及 Read View 的概念之后,我們模擬一下 MVCC 實(shí)現(xiàn)的整體流程。

  1. 假設(shè)當(dāng)前有四個(gè)事務(wù),當(dāng)事務(wù)2對某行數(shù)據(jù)執(zhí)行了快照讀,數(shù)據(jù)庫為該行數(shù)據(jù)生成一個(gè) Read View 讀視圖,假設(shè)當(dāng)前事務(wù)ID為2,此時(shí)還有事務(wù)1和事務(wù)3在活躍中,事務(wù)4在事務(wù)2快照讀前一刻提交更新了,所以 Read View 記錄了系統(tǒng)當(dāng)前活躍事務(wù)1,3的ID,維護(hù)在一個(gè)列表上,假設(shè)我們稱為 trx_list 。





    事務(wù)1事務(wù)2事務(wù)3事務(wù)4事務(wù)開始事務(wù)開始事務(wù)開始事務(wù)開始………修改且已提交進(jìn)行中快照讀進(jìn)行中
    ………
  2. Read View 不僅僅會(huì)通過一個(gè)列表 trx_list 來維護(hù)事務(wù)2執(zhí)行快照讀那刻系統(tǒng)正活躍的事務(wù)ID,還會(huì)有兩個(gè)屬性 up_limit_id(記錄 trx_list 列表中事務(wù)ID最小的ID),low_limit_id(記錄 trx_list 列表中事務(wù)ID最大的ID,也有人說快照讀那刻系統(tǒng)尚未分配的下一個(gè)事務(wù)ID也就是目前已出現(xiàn)過的事務(wù)ID的最大值+1,所以在這里例子中 up_limit_id 就是1,low_limit_id 就是4 + 1 = 5,trx_list 集合的值是1,3,Read View 如下圖

    59bc447c2ce168b3f880bf039e852c29.jpeg
  3. 我們的例子中,只有事務(wù)4修改過該行記錄,并在事務(wù)2執(zhí)行快照讀前,就提交了事務(wù),所以當(dāng)前該行當(dāng)前數(shù)據(jù)的 undo log 如下圖所示;我們的事務(wù)2在快照讀該行記錄的時(shí)候,就會(huì)拿該行記錄的 DB_TRX_ID 去跟 up_limit_id , low_limit_id 和活躍事務(wù)ID列表( trx_list )進(jìn)行比較,判斷當(dāng)前事務(wù)2能看到該記錄的版本是哪個(gè)。

    0d06227f939fe73269d74daeb403e0bc.jpeg
  4. 所以先拿該記錄 DB_TRX_ID 字段記錄的事務(wù)ID 4去跟 Read View 的的 up_limit_id 比較,看4是否小于 up_limit_id(1),所以不符合條件,繼續(xù)判斷 4 是否大于等于 low_limit_id(5),也不符合條件,最后判斷4是否處于 trx_list 中的活躍事務(wù), 最后發(fā)現(xiàn)事務(wù)ID為4的事務(wù)不在當(dāng)前活躍事務(wù)列表中, 符合可見性條件,所以事務(wù)4修改后提交的最新結(jié)果對事務(wù)2快照讀時(shí)是可見的,所以事務(wù)2能讀到的最新數(shù)據(jù)記錄是事務(wù)4所提交的版本,而事務(wù)4提交的版本也是全局角度上最新的版本。

&nbsp;

流程圖

1548a3bf6cf883b437b78543175d9aca.jpeg

2.5 RC/RR級別快照讀有什么不同

生成 Read View 的時(shí)機(jī)不同,從而造成 RC RR 級別下快照讀的結(jié)果的不同。

  • 在RR級別下的某個(gè)事務(wù)對某條記錄進(jìn)行的第一次快照讀會(huì)創(chuàng)建一個(gè)快照 Read View,此后在調(diào)用快照讀的時(shí)候,使用的還是同一個(gè)ReadView,所以只要當(dāng)前事務(wù)在其他事務(wù)提交更新之前使用過快照讀,那么之后的快照讀使用的都是同一個(gè)Read View,所以對之后的修改不可見.
  • 而在 RC 隔離級別下,事務(wù)中每次快照都會(huì)生成一個(gè)快照和 ReadView,這就是我們在 RC 級別下的事務(wù)中可以看到別的事務(wù)提交更新的原因。

總之在 RC 隔離級別下,每次快照讀都會(huì)生成最新的 ReadView;而在 RR 級別下,則是同一個(gè)事務(wù)中的第一個(gè)快照讀才會(huì)創(chuàng)建ReadView,之后的快照讀獲取的都是同一個(gè) ReadView。所以說 RR 在 RC 的基礎(chǔ)上通過生成 Read View 的時(shí)機(jī)不同從而解決了不可重復(fù)讀的問題

總結(jié)

本文講解了 MySQL 中的隱式字段、undo log 日志和 Read View 的原理以及 MVCC 的實(shí)現(xiàn)流程,對于我們在日常的開發(fā)過程中對于數(shù)據(jù)庫的并發(fā)操作以及 MySQL 的各種隔離級別有了清晰的認(rèn)識。

http://www.risenshineclean.com/news/4701.html

相關(guān)文章:

  • 在線免費(fèi)貨源網(wǎng)站入口站長之家下載
  • 房地產(chǎn)開發(fā)公司取名網(wǎng)站關(guān)鍵詞優(yōu)化排名軟件
  • 做網(wǎng)站需要的大圖電商網(wǎng)站策劃
  • 汽車之家這樣的網(wǎng)站怎么做杭州網(wǎng)站運(yùn)營十年樂云seo
  • 微網(wǎng)站制作價(jià)格金華關(guān)鍵詞優(yōu)化平臺
  • 可不可以用帝國cms做企業(yè)網(wǎng)站鄭州網(wǎng)站推廣公司
  • 建設(shè)銀行簽名通在網(wǎng)站哪里下載免費(fèi)制作自己的網(wǎng)頁
  • jq 網(wǎng)站模板技能培訓(xùn)網(wǎng)站
  • 西安哪家網(wǎng)絡(luò)公司做網(wǎng)站小說百度搜索風(fēng)云榜
  • 安陽工學(xué)院圖書館找做網(wǎng)站的書在哪免費(fèi)新聞源發(fā)布平臺
  • 彩票網(wǎng)站里的統(tǒng)計(jì)怎么做短視頻推廣渠道
  • 房地產(chǎn)網(wǎng)站怎么推廣優(yōu)化軟件下載
  • 2015年做啥網(wǎng)站能致富網(wǎng)絡(luò)營銷策劃的概念
  • 網(wǎng)站建設(shè)要考關(guān)鍵詞查詢工具包括哪些
  • 網(wǎng)站首頁動(dòng)畫效果怎么弄推廣廣告
  • 怎么看網(wǎng)站日志文件seo官網(wǎng)優(yōu)化
  • 房屋 哪個(gè)網(wǎng)站做的最好百度上的廣告多少錢一個(gè)月
  • 一個(gè)獨(dú)立IP做幾個(gè)網(wǎng)站比較合適seo網(wǎng)站建設(shè)優(yōu)化
  • 人妖和美女做視頻網(wǎng)站如何建立公司網(wǎng)站網(wǎng)頁
  • 網(wǎng)站建設(shè)合同糾紛問題百度廣告聯(lián)盟賺廣告費(fèi)
  • 官方網(wǎng)站建設(shè)要點(diǎn)最近三天的新聞大事簡短
  • 太平洋保險(xiǎn)網(wǎng)站做的這么爛打廣告推廣怎么做
  • 分類網(wǎng)站建設(shè)方案廣州網(wǎng)站優(yōu)化
  • 怎么找網(wǎng)站模板seo搜索引擎入門教程
  • 網(wǎng)站開發(fā)有哪些要求咖啡seo是什么意思
  • 泰安做網(wǎng)站哪家好企業(yè)網(wǎng)站制作方案
  • 浦東新區(qū)網(wǎng)站建設(shè)公司哪家靠譜奇葩網(wǎng)站100個(gè)
  • html 網(wǎng)站地圖北京seo顧問推推蛙
  • 臨沂最好的做網(wǎng)站公司網(wǎng)絡(luò)推廣費(fèi)用高嗎
  • 網(wǎng)站開發(fā)需要團(tuán)隊(duì)怎么做互聯(lián)網(wǎng)推廣