最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL多版本并發(fā)控制mvcc原理淺析

 更新時間:2024年07月21日 15:38:14   作者:雨下的竹子  
mvcc多版本并發(fā)控制是一種數(shù)據(jù)庫的并發(fā)控制機制,本文主要介紹了MySQL多版本并發(fā)控制mvcc原理淺析,具有一定的參考價值,感興趣的可以了解一下

1.mvcc簡介

1.1mvcc定義

mvcc(Multi Version Concurrency Control),多版本并發(fā)控制,是一種數(shù)據(jù)庫的并發(fā)控制機制。它用于管理事務(wù)并發(fā)執(zhí)行時對數(shù)據(jù)的訪問和修改,保證在多個事務(wù)同時對數(shù)據(jù)庫進行讀寫操作,不會出現(xiàn)數(shù)據(jù)不一致或丟失的情況

1.2mvcc解決的問題

當(dāng)多個事務(wù)同時訪問數(shù)據(jù)庫中的相同數(shù)據(jù)時,可能會有幾種情況:

  • 讀:多個事務(wù)都是讀操作,不會產(chǎn)生并發(fā)問題
  • 讀+寫:事務(wù)有讀有寫,那么會產(chǎn)生臟讀、不可重復(fù)讀、幻讀的問題
  • 寫:多個事務(wù)同時寫,可能會產(chǎn)生數(shù)據(jù)丟失、覆蓋等問題

針對以上問題,在讀+寫的情況下,通常需要加鎖來解決問題,mysql的innodb實現(xiàn)了mvcc來更好的處理讀寫沖突,做到不用加鎖,實現(xiàn)非阻塞并發(fā)讀

在都是寫操作的情況下,只能通過加鎖的方式解決。

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

當(dāng)前讀:讀取的是最新版本的數(shù)據(jù),保證讀取時不會有其他事務(wù)修改數(shù)據(jù),需要對記錄加鎖

加共享鎖,讀不受影響,寫會被阻塞

select ... lock in share mode;

加排他鎖,讀和寫都被阻塞(快照讀不受影響)

select ... for update;

更新、插入、刪除操作以及串行化隔離級別都是當(dāng)前讀

快照讀:每一次修改數(shù)據(jù),都會在undolog中存有原始記錄(快照),快照讀就是讀取某一版本的記錄。這種方式能夠不加鎖讀數(shù)據(jù),但是可能會讀到舊的數(shù)據(jù)。一般的查詢都是快照讀

select * from tablename;

2.mvcc原理

mvcc主要通過行記錄中的隱藏字段、undolog和readview實現(xiàn)的

2.1隱藏字段

mysql的innodb引擎中,在每一行記錄中除了自定義的字段,還有3個隱藏的字段(innodb引擎)

  • row_id:如果表沒有自定義主鍵,那么會自動生成row_id作為主鍵
  • trx_id:記錄修改、新增這條記錄的事務(wù)id
  • roll_pointer:回滾指針,指向當(dāng)前記錄的上一個版本

2.2版本鏈

在修改數(shù)據(jù)時,mysql會向undolog中記錄數(shù)據(jù)原來的快照,用于進行回滾操作。undolog還能用來實現(xiàn)mvcc

如以下例子,mvcc生成版本鏈:

當(dāng)事務(wù)1001(trx_id=1001)執(zhí)行了 insert into user values(1,'竹子',23) 之后:

在這里插入圖片描述

當(dāng)事務(wù)1002(trx_id=1002)執(zhí)行了 update user set name='竹筍' where id=1 之后:

在這里插入圖片描述

當(dāng)事務(wù)1003(trx_id=1003)執(zhí)行了 update user set name='竹葉' where id=1 之后:

在這里插入圖片描述

可以看到,不同版本的數(shù)據(jù)被指針連接起來形成了一個鏈表。

當(dāng)我們要讀取時,如何判斷該讀取哪個版本呢?這就與生成的讀視圖有關(guān)了。

2.3ReadView

讀視圖用于決定事務(wù)可以讀到哪個版本的數(shù)據(jù)

它包含以下主要信息:

  • trx_ids:當(dāng)前mysql中所有活躍的事務(wù)id集合(沒提交或回滾的事務(wù)集)
  • low_limit_id:當(dāng)前出現(xiàn)的最大的事務(wù)id+1,表示下一個要分配的事務(wù)id
  • up_limit_id:當(dāng)前活躍的事務(wù)id集合中,最小的事務(wù)id
  • creator_trx_id:生成該ReadView視圖的事務(wù)的id

MySQL5.7版本的源碼對于這些信息的定義如下:

在這里插入圖片描述

插入一個注意事項:????????????????????????

start transaction不代表立即生成ReadView,而是在事務(wù)中第一次快照讀的時候生成ReadView,具體參考MySQL可重復(fù)讀隔離級別下開啟事務(wù)的一個注意事項

想要開啟事務(wù)時就生成ReadView,請使用

start transaction with consistent snapshot;

2.4讀視圖生成原則

ReadView定義了一個可見性算法,當(dāng)事務(wù)進行快照讀時,依據(jù)該算法判斷事務(wù)能夠讀取哪個快照。

源碼的可見性判斷邏輯如下:(下載源碼可訪問:官網(wǎng),操作系統(tǒng)選擇Source Code)

/** Check whether the changes by id are visible.
	@param[in]	id	transaction id to check against the view
	@param[in]	name	table name
	@return whether the view sees the modifications of id. */
//判斷某個版本的數(shù)據(jù)是否對當(dāng)前事務(wù)可見
bool changes_visible(
    trx_id_t		id,
    const table_name_t&	name) const
    MY_ATTRIBUTE((warn_unused_result)) {
    ut_ad(id > 0);
    //快照的id小于活躍事務(wù)id集合中的最小事務(wù)id 或者 快照的id等于創(chuàng)建這個視圖的事務(wù)id
    if (id < m_up_limit_id || id == m_creator_trx_id) {
        return(true);
    }
    //檢查快照id是否合法,如果快照的id大于等于下一要分配的事務(wù)id,則需要拋出警告信息(會出現(xiàn)這種情況嗎?)
    check_trx_id_sanity(id, name);
    //快照的id大于等于下一要分配的事務(wù)id
    if (id >= m_low_limit_id) {
        return(false);
    } 
    //當(dāng)前不存在活躍的事務(wù)
    else if (m_ids.empty()) {
        return(true);
    }
    const ids_t::value_type*	p = m_ids.data();
    //通過二分查找判斷快照id是否在活躍事務(wù)集合中,存在則快照不可見,不存在則快照可見
    return(!std::binary_search(p, p + m_ids.size(), id));
}
  • 當(dāng)快照id等于當(dāng)前事務(wù)id時(trx_id=creator_trx_id),說明該版本是當(dāng)前事務(wù)修改的,該快照對當(dāng)前事務(wù)可見
  • 當(dāng)快照id小于活躍事務(wù)的最小id(trx_id<up_limit_id),說明該版本對應(yīng)的事務(wù)已經(jīng)提交了,該快照對當(dāng)前事務(wù)可見
  • 當(dāng)快照id大于等于下一個要分配的事務(wù)id(trx_id>=low_limit_id),則該快照對當(dāng)前事務(wù)不可見
  • 當(dāng)快照id小于下一個要分配的事務(wù)id并且活躍事務(wù)id數(shù)量為0(trx_id<low_limit_id && trx_ids.size==0),則該快照對當(dāng)前事務(wù)可見
  • 當(dāng)以上條件都不滿足,則在活躍事務(wù)id集合里查找快照id,如果不存在,則可見,否則不可見

3.rc和rr隔離級別下mvcc的不同

mvcc主要用來解決rc(讀已提交)隔離級別下的臟讀和rr(可重復(fù)讀)隔離級別的不可重復(fù)讀問題,所以mvcc只在rc和rr隔離級別下生效。

區(qū)別在于,rc級別下,每一次快照讀都會生成一個最新的ReadView;RR級別下,只有事務(wù)中的第一次快照讀會生成ReadView,之后的快照讀會使用第一次生成的ReadView。

事務(wù)能否查詢到其他事物修改的數(shù)據(jù),取決于ReadView,而rc和rr兩個級別的ReadView生成方式不同,就導(dǎo)致了事務(wù)可見性不同。(rc級別下一個事務(wù)可以查詢到其他事物在此期間修改并提交的數(shù)據(jù),因為它的每次查詢都會生成新的ReadView;rr級別下事務(wù)無法查詢到其他事物在此期間修改并提交的數(shù)據(jù),因為他的ReadView只在第一次快照讀生成)

到此這篇關(guān)于MySQL多版本并發(fā)控制mvcc原理淺析的文章就介紹到這了,更多相關(guān)MySQL多版本并發(fā)控制mvcc內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL深分頁問題原理與三種解決方案

    MySQL深分頁問題原理與三種解決方案

    本文主要介紹了MySql深分頁問題原理與解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • mysql遇到load data導(dǎo)入文件數(shù)據(jù)出現(xiàn)1290錯誤的解決方案

    mysql遇到load data導(dǎo)入文件數(shù)據(jù)出現(xiàn)1290錯誤的解決方案

    這篇文章主要介紹了mysql遇到load data導(dǎo)入文件數(shù)據(jù)出現(xiàn)1290錯誤的解決方案,非常的簡單實用,有需要的小伙伴可以參考下
    2018-07-07
  • MySQL為時間字段設(shè)置默認當(dāng)前時間的方法技巧

    MySQL為時間字段設(shè)置默認當(dāng)前時間的方法技巧

    文章詳細介紹了MySQL中記錄創(chuàng)建時間和最后修改時間的最佳實踐,包括時間類型的支持、默認值函數(shù)的使用、MySQL版本的演進、常見錯誤的修復(fù)以及高級技巧,建議使用DATETIME或TIMESTAMP類型,并在DEFAULT子句中使用CURRENT_TIMESTAMP函數(shù),需要的朋友可以參考下
    2026-02-02
  • 一文帶你解鎖MySQL實現(xiàn)行轉(zhuǎn)列的完整方法

    一文帶你解鎖MySQL實現(xiàn)行轉(zhuǎn)列的完整方法

    MySQL的行轉(zhuǎn)列,不是簡單的語法堆砌,而是對數(shù)據(jù)結(jié)構(gòu)深刻理解后的重構(gòu),這篇文章主要介紹了MySQL實現(xiàn)行轉(zhuǎn)列的完整方法,有需要的小伙伴可以了解下
    2026-01-01
  • 使用Canal實現(xiàn)MySQL主從同步的流程步驟

    使用Canal實現(xiàn)MySQL主從同步的流程步驟

    這篇文章主要介紹了如何使用Canal實現(xiàn)MySQL主從同步效果,文中通過代碼示例和圖文結(jié)合的方式給大家講解的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • MySQL分類排名和分組TOP N實例詳解

    MySQL分類排名和分組TOP N實例詳解

    大家好,本篇文章主要講的是MySQL分類排名和分組TOP N實例詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • MySQL?索引簡介及常見的索引類型有哪些

    MySQL?索引簡介及常見的索引類型有哪些

    MySQL索引是加速數(shù)據(jù)檢索的特殊結(jié)構(gòu),用于存儲列值與位置信息,常見的索引類型包括:主鍵索引、唯一索引、普通索引、復(fù)合索引、全文索引和空間索引等,本文介紹MySQL索引簡介及常見的索引類型有哪些,感興趣的朋友一起看看吧
    2025-08-08
  • mysql多個left join連接查詢用法分析

    mysql多個left join連接查詢用法分析

    這篇文章主要介紹了mysql多個left join連接查詢用法,結(jié)合實例形式對比分析了mysql使用left join進行連接查詢相關(guān)操作技巧與注意事項,需要的朋友可以參考下
    2018-07-07
  • 在windows環(huán)境下配置并隨意切換兩種mysql版本的方法

    在windows環(huán)境下配置并隨意切換兩種mysql版本的方法

    這篇文章主要介紹了mysql:如何在windows環(huán)境下配置并隨意切換兩種mysql版本,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01
  • 詳解MySQL數(shù)據(jù)庫千萬級數(shù)據(jù)查詢和存儲

    詳解MySQL數(shù)據(jù)庫千萬級數(shù)據(jù)查詢和存儲

    百萬級、千萬級數(shù)據(jù)處理,核心關(guān)鍵在于數(shù)據(jù)存儲方案設(shè)計,存儲方案設(shè)計的是否合理,直接影響到數(shù)據(jù)CRUD操作??傮w設(shè)計可以考慮一下幾個方面進行設(shè)計考慮:數(shù)據(jù)存儲結(jié)構(gòu)設(shè)計;索引設(shè)計;數(shù)據(jù)主鍵設(shè)計;查詢方案設(shè)計。
    2021-05-05

最新評論

贡山| 黄骅市| 贞丰县| 扎兰屯市| 敖汉旗| 永州市| 汾阳市| 洛宁县| 聂荣县| 石楼县| 保定市| 郎溪县| 天全县| 朝阳市| 罗江县| 四会市| 习水县| 静海县| 长白| 漳平市| 新丰县| 华亭县| 图木舒克市| 日土县| 兴文县| 阳原县| 莎车县| 天津市| 彭水| 河池市| 年辖:市辖区| 九台市| 东海县| 辉南县| 新竹市| 修文县| 铜山县| 鞍山市| 贵州省| 大连市| 郯城县|