MySQL 筆記整理(8.a) --事務到底是隔離還是不隔離的?

来源:https://www.cnblogs.com/dogtwo0214/archive/2019/03/04/10472405.html
-Advertisement-
Play Games

筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》 8.a) --事務到底是隔離還是不隔離的? 這部分內容不太容易理解,筆者也是進行了多次閱讀。因此引用原文: 之前有提到過,如果是在可重覆讀隔離級別,事務T啟動的時候會創建一個視圖read-view,之後事務T執行期間,即使有其他事務修改了數據, ...


筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》

8.a) --事務到底是隔離還是不隔離的?

  這部分內容不太容易理解,筆者也是進行了多次閱讀。因此引用原文:

  之前有提到過,如果是在可重覆讀隔離級別,事務T啟動的時候會創建一個視圖read-view,之後事務T執行期間,即使有其他事務修改了數據,事務T看到的仍然跟在啟動時看到的一樣,也就是說,一個在可重覆讀隔離級別下執行的事務,好像與世無爭,不受外界影響。

  但是,在之前也行鎖相關內容時又提到,一個事務要更新一行,如果剛好有另外一個事務擁有這一行的行鎖,它又不能這麼超然了,會被鎖住,進入等待狀態。問題是,既然進入了等待狀態,那麼等到事務自己獲取到行鎖要更新數據的時候,它讀到的值又是什麼呢?

  舉一個例子,下麵是一個只有兩行的表的初始化語句。

mysql> CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `k` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t(id, k) values(1,1),(2,2);

    圖一, 事務A, B, C的執行流程

 

  這裡我們需要註意的是事務的啟動時機。

  begin/start transaction命令並不是一個事務的起點,在執行到它們之後的第一個操作InnoDB表的語句,事務才真正啟動。如果你想要馬上啟動一個事務,可以使用start transaction with consistent snapshot命令。

  • 第一種啟動方式,一致性視圖是在執行第一個快照讀語句時創建的。
  • 第二種啟動方式,一致性視圖是在執行start transaction with consistent snapshot時創建的。

  還需要註意,沒有特殊說明的情況下,我們預設autocommit=1.

  在上面這個例子中,事務C沒有顯示的使用begin/commit,表示這個update語句本身就是一個事務,語句完成時會自動提交。事務B在更新了行之後查詢;事務A在一個只讀事務中查詢,並且時間順序上是在事務B的查詢之後。這時候,如果告訴你事務B查詢到的K值是3,而事務A查到的k的值是1,你是不是感覺有點暈呢?

  所以今天這篇文章就是想和你說明這個問題。在MySQL里有兩個視圖概念:

  • 一個是view,它是一個用查詢語句定義的虛擬表,在調用的時候執行查詢語句並生成結果。創建視圖的語法是create view...,而它的查詢方法與表一樣。
  • 另一個是InnoDB在實現MVCC時用到的一致性視圖,即consistent read view,用於支持RC(Read Commited 讀提交)和RR(Repeatable Read,可重覆讀)隔離級別的實現。

  它沒有物理結構,作用是事務執行期間用來定義“我能看到什麼數據”.

“快照”在MVCC里是怎麼工作的?

  在可重覆讀的隔離級別下,事務在啟動的時候就“拍了個快照”,註意,這個快照是基於整個資料庫的。這時,你可能覺得這不太現實,畢竟如果一個庫有100G,那麼我啟動一個事務,MySQL就要拷貝100G的數據,這個過程得多慢啊。可是平常執行事務卻很快。實際上,並不需要拷貝這100G的數據。我們先來看看這個快照是怎麼實現的。

  InnoDB裡面每個事務有一個唯一的事務ID,叫做transaction id。它是在事務開始的時候向InnoDB的事務系統申請的,是按申請順序嚴格遞增的。

  而且,每行數據也是有多個版本的,每次事務更新的時候,都會生成一個新的數據版本,並且把transaction id 賦值給這個數據版本的事務ID,記為row trx_id。同時,舊的數據版本要保留,並且在新的數據版本中,能夠有信息可以直接拿到它。也就是說,數據表中的每一行記錄,其實可能有多個版本(row),每個版本有自己的row trx_id。

  如圖2所示,就是一個記錄被多個事務連續更新後的狀態。

  

    圖2 行狀態變更圖

  圖中虛線框里是同一行數據的4個版本,當前最新版本是V4,k的值是22,它是被transaction id為25的事務更新的,因此它的row trx_id也是25.你可能會問,前面的文章不是說,語句更新會生成undo log(回滾日誌)嗎?那麼,undo log在哪兒呢?實際上,圖2中的三個虛線箭頭,就是undo log;而V1,V2,V3並不是物理上真實存在的,而是每次需要的時候根據當前版本和undo log計算出來的。比如,需要V2的時候,就是通過V4依次執行U3,U2算出來。明白了多版本和row trx_id的概念後,我們再來想一下,InnoDB是怎麼定義那個“100G”的快照的。按照可重覆讀的定義,一個事務啟動的時候,能夠看見所有已經提交的事務結果。但是之後,這個事務執行期間,其他事務的更新對它不可見。

  因此,一個事務只需要在啟動的時候聲明說,“以我啟動的時刻為準,如果一個數據版本在我啟動之前生成,就認;否則就不認。必須要找到它的上一個版本。當然,如果‘上一個版本’也不可見,那就得繼續往前找”。除此之外,如果這個事務自己更新的數據,它自己還是要認的。在實現上,InnoDB為每個事務構造了一個數組,用來保存這個事務啟動瞬間,當前正在“活躍”的所有事務ID。“活躍”指的就是,啟動了但還沒提交。數組裡面事務ID的最小值記為低水位,當前系統裡面已經創建過的事務ID的最大值加1記為搞水位。這個視圖數組和高水位,就組成了當前事務的一致性視圖(read-view)。而數據版本的可見性規則,就是基於數據的row trx_id和這個一致性視圖的對比結果得到的。這個視圖數組把所有的 row trx_id分成了幾種不同的情況。

  

  圖3, 數據版本可見性規則

  這樣,對於當期事務的啟動瞬間來說,一個數據版本的row trx_id,有以下幾種可能:

  1. 如果落在綠色部分,表示這個版本是已提交的事務或者是當期事務自己生成的,這個數據是可見的。
  2. 如果落在紅色部分,表示這個版本是由將來啟動的事務生成的,是肯定不可見的。
  3. 如果落在黃色部分,那就包括兩種情況。a. 若row trx_id 在數組中,表示這個版本是由還沒提交的事務生成的,不可見。b.若 row trx_id不在數組中,表示這個版本是已經提交了的事務生成的,可見。

  所以你現在知道了,InnoDB利用了“所有數據都有多個版本”的這個特性,實現了“秒級創建快照”的能力。接下來我們回顧一下圖1中的三個事務,分析事務A的語句返回的結果,為什麼是k=1.

  未完待續.....


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、安裝Java JDK 2、安裝Elasticsearch 1、導入Elasticsearch的GPG公鑰 2、添加Elasticsearch倉庫源 3、安裝elasticsearch 4、安裝完成之後,配置Elasticsearch 5、啟動Elasticsearch服務並加入開機自啟 3、安裝 ...
  • 1.處理目錄的命令 2.查看文件指令 3.鏈接文件 ln 命令保證鏈接文件的同步性,無論改動哪一處文件,其他文件都會發生相應的變化 4.文件許可權 在Linux中第一個字元代表這個文件是目錄、文件或鏈接文件等等。 當為[ d ]則是目錄 當為[ - ]則是文件; 若是[ l ]則表示為鏈接文檔(lin ...
  • 安裝Head插件 由於head插件本質上還是一個nodejs的工程,因此需要安裝node,使用npm來安裝依賴的包。 <1>安裝Node.js 下載解壓 配置並生效 查看版本驗證 <2>下載head插件 如果未安裝git ,則先安裝git工具 <3>安裝grunt <4>安裝插件 在elastics ...
  • 直接使用root賬號 1、zookeeper安裝 將zookeeper 3.4.13.tar.gz安裝包放置指定目錄 2、zookeeper安裝可視化工具 需要安裝 java和maven環境 1、安裝maven環境 線上下載地址,不用管 http://mirrors.shu.edu.cn/apach ...
  • 1、增增加目錄命令:mkdir 映射--1.新建目錄名為dir1 eg:mkdir dir1 2.一次建多個文件夾eg:temp1,temp2,temp3 mkdir temp1 temp2 temp3 3.新建父目錄,文件已存在也不會報錯; eg:mkdir -p t1/t2/t3增加文件命令:t ...
  • 背景:從軟通出來,告別華為外包,離開H區,進入了一家搞大數據的創業公司,感覺周圍都好陌生,記錄下自己大數據的career! 2019-03-4新的徵程-入職第一天: 一、辦理入職手續 公司人比較少,沒有入職培訓等操作;用了企業微信和企業郵箱,填下個人信息,然後開搞; 二、搭建Java開發環境和虛擬機 ...
  • 今天在調試使用ansible進行標準化安裝MySQL8.0時,發現關於caching_sha2_password plugin的一個bug。 在搭建主從複製時,按照手冊說明需要創建用戶: 然後在從庫執行: 悲催的是,發現從庫的IO_Thread提示連不上主庫。 而如果在從庫上直接使用mysql命令行 ...
  • 1:主鍵和外鍵的定義 主鍵(primary key):一列(或一組列),其值能夠唯一區分表中每個行 。外鍵(foreign key) 外鍵為某個表中的一列,它包含另一個表的主鍵值,定義了兩個表之間的關係 借用其他博客中的三個數據表解析一下: 2:是哪個表的外鍵? 以上面的成績表為例,學號和課程號是成 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...