<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        

      MVCC總結

      一、MVCC機制是什么

      MVCC,即Multi-Version Concurrency Control (多版本并發控制)。它是一種并發控制的方法,一般在數據庫管理系統中,實現對數據庫的并發訪問,在編程語言中實現事務內存。

      個人理解

      1. MySQL 的 InnoDB 存儲引擎支持事務。
      2. 事務的四大特性:A 原子性、C 一致性、I 隔離性、D 持久性
      3. 原子性:事務是一組sql,這組sql要么全部執行成功,要么全都不執行。
      4. 事務的并發會帶來并發問題,臟讀、不可重復讀、幻讀。
      5. 為了解決事務并發問題,MySQL提供了不同的隔離級別,來控制并發事務之間的隔離程度。不同的隔離級別在并發性能和數據一致性方面具有不同的權衡。例如,較低的隔離級別可以提高并發性能,但可能會導致數據一致性問題;而較高的隔離級別可以保證數據一致性,但可能會降低并發性能。
        1. 四種隔離級別:讀未提交 RU、讀已提交 RC、可重復讀 RR、串行化 S
      6. 現在回答MVCC 機制是什么,MVCC 機制是為了控制事務并發產生的并發問題的一種機制,并且根據隔離級別不同,所表現出來的機制是不同的。

      二、MVCC機制解決了什么問題

      MVCC 機制,
      在RC 級別下,存在不可重復讀的問題,每次執行SQL都會生成ReadView。
      在RR 級別下,解決了不可重復讀的問題,只會生成一次ReadView。
      兩種隔離級別下的解決思路不同。

      三、MVCC 的實現

      MVCC 通過undolog日志和ReadView實現。

      3.1、隱藏字段

      InnoDB 存儲引擎的每一行都有兩個隱藏字段trx_id、roll_pointer,如果表中沒有主鍵索引或者唯一索引列,那么還會增加一個row_id字段。

      列名 是否必須 描述
      trx_id 事務 id,創建事務時生成
      roll_pointer 回滾點,指向回滾段的undo日志
      row_id 不是必需的,占用6個字節.

      3.2、undolog 日志

      undo log,回滾日志,用于記錄數據被修改前的信息。在表記錄修改之前,會先把數據拷貝到undo log里,如果事務回滾,即可以通過undo log來還原數據。
      可以這樣認為,當delete一條記錄時,undo log 中會記錄一條對應的insert記錄,當update一條記錄時,它記錄一條對應相反的update記錄。

      undolog 的作用 :

      1. 事務回滾:保證原子性和一致性
      2. 用于MVCC 的快照讀

      3.3、版本鏈

      同一條記錄的多次修改,會產生不同的版本,這些不同的版本通過隱藏字段roll_pointer連接。

      主體是記錄,事務并發時,每一條記錄都是一個鏈表的形式。

      image.png
      以一個流程講解版本鏈的生成流程

      1. 版本鏈的頭結點是最新的值
      2. 最新的值存在數據庫中
      3. 除最新的值之外的值,存在undolog日志中

      update user set name ="李四" where id=1

      • 首先獲得一個事務ID=100,trx_id = 102(事務開始時,生成事務id)
      • 把user表修改前的數據,拷貝到undo log(更新undolog日志)
      • 修改user表中,id=1的數據,名字改為李四 (修改數據表中的數據)
      • 把修改后的數據事務Id=102改成當前事務版本號,并把roll_pointer指向undo log數據地址。

      3.4、快照讀和當前讀

      快照讀:讀取的是記錄數據的可見版本(有舊的版本)。不加鎖,普通的select語句都是快照讀
      **select** * **from** core_user **where** id > 2;
      當前讀:讀取的是記錄數據的最新版本,顯式加鎖的都是當前讀

      select * from core_user where id > 2 for update;  排他鎖 / 寫鎖
      select * from account where id>2 lock in share mode;  共享鎖 / 讀鎖
      

      3.5、ReadView和數據可見性算法

      ReadView 是什么?
      在innodb 存儲引擎中,每個SQL語句執行前都會得到一個Read View。它就是事務執行SQL語句時,產生的讀視圖。
      主要用來做可見性判斷,判斷當前事務可以看到的哪個版本的數據

      Readview 的幾個重要字段
      每個SQL語句執行前都會得到一個Read View。

      • creator_trx_id:創建當前read view的事務ID
      • m_ids:當前系統中那些活躍(未提交)的讀寫事務ID, 它數據結構為一個List。
      • min_limit_id:表示在生成ReadView時,當前系統中活躍的讀寫事務中最小的事務id,即m_ids中的最小值。
      • max_limit_id:表示生成ReadView時,系統中應該分配給下一個事務的id值

      數據可見性算法
      可見性算法看到的數據就是這個SQL語句能看到的數據行的版本。(在多個版本的數據中,根據事務IDtrx_id,選出適合當前SQL語句的數據行)。
      通過這四個數據和版本鏈上的數據作對比。(遍歷鏈表)
      當執行SQL的時候會生成事務ID,并且同時生成ReadView。

      1. trx_id < min_limit_id時,表明修改該數據行的事務提交發生在SQL查詢之前,所以該行數據可以被SQL查詢出來
      2. trx_id >= max_limit_id時,表明修改該數據行的事務發生在SQL查詢之后,所以該行數據不能被SQL查詢出來
      3. min_limit_id <= trx_id < max_limit_id時,分三種情況討論
        1. 如果m_ids包含trx_id,表明修改該數據行的事務還未提交,
          1. 如果 trx_id = creator_trx_id時,表明修改該數據行的事務就是當前的SQL的事務,所以可以看到該數據行
          2. 如果 trx_id != creator_trx_id時,表明修改該數據行的事務不是當前的SQL的事務,所以不能看到該數據行
        2. 如果m_ids不包含trx_id,表明修改該數據行的事務已經被提交了,所以可以看到該數據行

      四、MVCC的執行流程

      4.1、MVCC 查詢一條記錄(SQL)的大致流程

      1. 獲取事務自己的版本號,即事務ID
      2. 獲取Read View (在RC隔離級別下,存在)
      3. 查詢得到的數據,然后Read View中的事務版本號進行比較。
      4. 如果不符合Read View的可見性規則, 即就需要Undo log中歷史快照;
      5. 最后返回符合規則的數據

      4.2、在RC隔離級別下,存在不可重復讀的問題分析

      先準備數據

      DROP TABLE IF EXISTS `student`;
      CREATE TABLE `student`  (
        `id` int(11) NOT NULL,
        `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
        PRIMARY KEY (`id`) USING BTREE
      ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
      
      -- ----------------------------
      -- Records of student
      -- ----------------------------
      INSERT INTO `student` VALUES (1, '小明');
      

      設置當前隔離級別為RC

      # 查看隔離級別
      show variables like 'transaction_isolation';
      # 全局修改隔離級別
      SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
      # SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
      

      事務并發SQL語句

      # 事務A,兩次查看同一條數據
      BEGIN; # 1
      select * from student; # 2 輸出 name為 aaa
      select * from student; # 6 輸出 name為 bbb
      COMMIT; # 7
      
      # 事務B,修改數據
      BEGIN; # 3
      UPDATE student SET name = 'bbb' WHERE id = 1; # 4
      COMMIT; # 5
      

      兩個事務開兩個會話

      流程分析:

      1. 生成事務A的id,假設為100
      2. 生成該SQL的ReadView,
      m_ids min_limit_id max_limit_id creator_trx_id
      [100] 100 101 100
      1. 生成事務B的id,假設為101
      2. 生成該SQL的ReadView,
      m_ids min_limit_id max_limit_id creator_trx_id
      [100,101] 100 102 101
      1. 事務B提交
      2. 生成該SQL的ReadView,因為是RC隔離級別,所以每一次執行SQL都重新生成ReadView
      m_ids min_limit_id max_limit_id creator_trx_id
      [100] 100 103 100

      查找所有記錄行的版本鏈,從鏈表頭開始遍歷,此時的版本鏈如下,

      使用ReadView 和 每一行數據的版本鏈做比較,比較過程如下

      • min_limit_id(100) <= trx_id (101) < max_limit_id(103) 并且 m_ids 不包含 trx_id,說明在生成ReadView時,記錄的修改已經提交,所以對最新的數據行bbb對該SQL是可見的。
      • 返回數據庫的bbb那一行的數據。
      1. 事務A提交

      結論:可以看到,第2步和第6步返回的數據不同,發生了不可重復的問題。

      4.3、在RR隔離級別下,解決不可重復讀

      修改全局隔離級別,需要新開一個會話

      SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
      show variables like 'transaction_isolation';
      

      之前的過程是相同的,進行到第6步時,發生了不同
      因為是RR 的隔離級別,所以只會生成一次ReadView
      所以,第6步的ReadView 和 第2步是相同的
      1-5 同上 。。。

      1. 生成該SQL的ReadView,因為是RR隔離級別,所以只會生成一次ReadView,使用第2步時的ReadView
      m_ids min_limit_id max_limit_id creator_trx_id
      [100] 100 101 100

      版本鏈還是上面的
      比較過程如下:

      • trx_id(101) >= max_limit_id(101),說明這個版本的數據的修改,發生在生成ReadView之后,所以對該ReadView 來說,這個版本的數據是不可見的,根據roll_pointer遍歷上一個版本
      • trx_id(1) < min_limit_id(100),說明這個版本的數據的修改,發生在生成ReadView之前,所以對該ReadView 來說,這個版本的數據是可見的,所以返回 aaa 這一行的數據
      1. 同上,事務A提交
      posted @ 2023-10-20 22:28  永恒&  閱讀(68)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产av成人精品播放| 成人无码视频在线观看免费播放| 国产精品亚洲综合久久小说| 18禁黄无遮挡网站免费| 中文字幕第一页国产精品| 欧美另类videossexo高潮| 国产日韩乱码精品一区二区| 在线高清免费不卡全码| 欧美性猛交xxxx乱大交丰满| 亚洲欧美电影在线一区二区| 成人免费无码视频在线网站| 乱60一70归性欧老妇| 亚洲av永久无码精品网站| 亚洲精品无码成人A片九色播放| 国产精品一二三区蜜臀av| 日韩不卡手机视频在线观看| 欧洲性开放老太大| 五月婷之久久综合丝袜美腿| 免费看婬乱a欧美大片| 美女黄18以下禁止观看| 亚洲欧洲精品日韩av| 国产精品熟女乱色一区二区| 国产欧美日韩另类在线专区| 日韩乱码人妻无码中文字幕视频| 色综合视频一区二区三区| 日韩成人午夜精品久久高潮| 亚洲天堂视频网| 免费看成人欧美片爱潮app| 无码免费大香伊蕉在人线国产| 亚洲av永久无码精品网站| 亚洲人成人日韩中文字幕| 广宁县| 久久精品无码一区二区三区| 99精品热在线在线观看视| 亚洲欧美综合中文| 亚洲精品男男一区二区| 777奇米四色成人影视色区| 亚洲精品一区二区三区综合| 成 年 人 黄 色 大 片大 全| 国产免费午夜福利蜜芽无码| 好紧好爽午夜视频|