MVCC read view的问题
之前写了一篇文章以为对MVCC的大致原理有些了解了。今天看了《高性能MySQL》的时候,深究了一下read view的问题,发现还是蛮有意思的。 特别画了一张图来确认一下。 本文是上一篇MySQL事务和MVCC简介的后续,建议先了解上一篇文章以后再阅读本文。 上一篇文
之前写了一篇文章以为对MVCC的大致原理有些了解了。今天看了《高性能MySQL》的时候,深究了一下read view的问题,发现还是蛮有意思的。
特别画了一张图来确认一下。
本文是上一篇MySQL事务和MVCC简介的后续,建议先了解上一篇文章以后再阅读本文。
上一篇文章简单描述了MVCC的相关情况,但是没有详细说,read view是什么结构,并且它到底是怎么工作的。
比如,我们在show engine innodb status可以看到如下内容:
- ? —TRANSACTION 0 600, ACTIVE 4 sec, process no 3396, OS thread id 1148250464, thread declared inside InnoDB 442
- ? mysql tables in use 1, locked 0
- ? MySQL thread id 8079, query id 728899 localhost baron Sending data
- ? select sql_calc_found_rows * from b limit 5
- ? Trx read view will not see trx with id>= 0 601, sees
要理解这个,我们首先要知道:
read view其实就是一个保存事务ID的list列表。记录的是本事务执行时,MySQL还有哪些事务在执行。
Read Repeatable(下文和图中用RR表示)对应的是在每个事务启动的时候创建 一个Read View。
Read Commit(下文和图中用RC表示)对应的是每次执行SQL statement时候创建?一个Read View。
根据show engine innodb status的输出是说看到这个事务的id是600。
对这个事务来说,trx id为596以下的所有事务修改的行数据,这个事务都可以看到,
trx id在601以上的事务修改的数据,这个事务都不应该读取到。
596到601号事务,一共5个事务修改的数据无法确定是否能够读取。read view应该为这5个事务id集合的子集。
如果线程的隔离级别是RR:
按照show engine innodb status的输出,600号事务在事务启动的时候,MySQL告诉它:
596之前的所有事务都已经提交了(Trx read view will not see trx with id>= 0 601, sees ),
由于事务本身是600号,那么对应的601号事务因为是在它后面启动的,600号事务肯定无法提供读取到数据(Trx read view will not see trx with id>= 0 601,?sees
read view表示的是事务开始时MySQL还有哪些事务在执行,就应该为{596,597,598,599}集合的子集,假设为{596,598},
根据read view,Innodb在读取数据的时候需要判断该行数据的修改事务号,判断的方法为:
a)?如果行数据的修改事务号小于596,由于在事务启动的时候596之前的所有线程都已经提交了,那么该行数据可读。
b) 如果行数据的修改事务号大于601,那么该行数据肯定不可读。如果事务号为600(即自己),本事务未提交,当然也是不可读的。
为了保证在事务内任何时间读取的数据都是一致的,需要根据行数据的undo信息回溯,每次回溯都需要进行a),b),c),d)的判断,直到找到一个可读的数据。
c) 如果行数据的修改事务号在read view里面{596,599},说明是该事务(600号)开始时没有提交的数据修改,
为了保证在事务内任何时间读取的数据都是一致的,需要根据行数据的undo信息回溯,每次回溯都需要进行a),b),c),d)的判断,直到找到一个可读的数据。
d)如果不在read view里面,即事务id号在{597,598}中,说明修改行数据是该事务(600号)开始时已经提交的数据修改,那么该行数据可读。
图1 MySQL read view 示意图
如图1。这个事务的行修改数据在{[0~595],597,598}是可读区间,{596,599,600,[601~ +infinity]}是不可读区间。
如果线程的隔离级别是RC,线程开始的时候,RC事务并不会做read view,此时开始的SQL跟上面RR的情况可能是一样的。
但是过了一段时间如果601事务提交了,同样的查询,在RC下面提交,对应的show engine innodb status的信息可能稍微有点不同:
- ? —TRANSACTION 0?600, ACTIVE 4 sec, process no 3396, OS thread id 1148250464, thread declared inside InnoDB 442
- ? mysql tables in use 1, locked 0
- ? MySQL thread id 8079, query id 728899 localhost baron Sending data
- ? select sql_calc_found_rows * from b limit 5
- ??Trx read view will not see trx with id>= 0 602, sees
按照输出,600号事务在语句“select sql_calc_found_rows * from b limit 5”发起的时候,MySQL告诉它:
596之前的所有事务都已经提交了(Trx read view will not see trx with id>= 0 601,?sees ),
对应的,602号线程以及它之后的所有线程都还未提交(Trx read view?will not see trx with id>= 0 602,?sees
read view表示的是语句开始时MySQL还有哪些事务在执行(注意,这里跟RR为事务开始的时候的read view不同了),
在一个事务里面,每个SQL执行的时候,它的read view都可能是不同的。有可能事务启动的时候的sql的read view为{596,598},
这个语句执行的时候,601事务提交了,read view为{596,598}。
注意,601号事务虽然在600事务后启动,此时已经提交了行数据修改,它修改的数据,600号线程也可以读到。
根据read view,InnoDB在读取数据的时候需要判断该行数据的修改事务号,判断的方法为:
a)?如果行数据的修改事务号小于596,由于在语句启动的时候596之前的所有线程都已经提交了,那么该行数据可读。
b) 如果行数据的修改事务号大于等于602,那么该行数据肯定不可读。如果事务号为600(即自己),本事务未提交,当然也是不可读的。
为了保证读到的是Commited的数据,需要根据行数据的undo信息回溯,每次回溯都需要进行a),b),c),d)的判断,直到找到一个可读的数据。
c) 如果行数据的修改事务号在read view里面{596,599},说明是该语句开始时没有提交的数据修改,
为了保证读到的是Commited的数据,需要根据行数据的undo信息回溯,每次回溯都需要进行a),b),c),d)的判断,直到找到一个可读的数据。
d)如果不在read view里面,即事务id号在{597,598}中,说明修改行数据是该语句开始时已经提交的数据修改,那么该行数据可读。
如图1。这个语句的修改行数据的事务id在{[0~595],597,598,601}是可读区间,{596,599,600,[602~ +infinity]}是不可读区间。
整体来说,这篇文章描述了在Read Readrepeatable和Read Commit环境下,MySQL根据Read View读取数据的方法,来保证可重复读和只读到已经提交的数据。
原文地址:MVCC read view的问题, 感谢原作者分享。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

一、今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! 1.開通基礎權益:原創文章選擇投放廣告可獲得收益,影片必須原創橫屏才會有收益。 2.開通百粉權益:粉絲量達百粉以上,微頭條、原創問答創作及問答均可獲得收益。 3.堅持原創作品:原創作品包含文章、微標題及問題等,要求300字以上。注意違規抄襲作品作為原創發布,會被扣信用分,即使有收益也會被扣除。 4.垂直度:做專業領域一類的文章,不能隨意跨領域寫文章,會得不到合適的推薦,達不到作品的專和精,難以吸引粉絲讀者。 5.活躍度:活躍度高,

聚類演算法中的聚類效果評估問題,需要具體程式碼範例聚類是一種無監督學習方法,透過對資料進行聚類,將相似的樣本歸為一類。在聚類演算法中,如何評估聚類的效果是一個重要的問題。本文將介紹幾種常用的聚類效果評估指標,並給出對應的程式碼範例。一、聚類效果評估指標輪廓係數(SilhouetteCoefficient)輪廓係數是透過計算樣本的緊密度和與其他簇的分離度來評估聚類效

iPhone以其強大的性能和多方面的功能而聞名,它不能倖免於偶爾的打嗝或技術困難,這是複雜電子設備的共同特徵。遇到iPhone問題可能會讓人感到沮喪,但通常不需要警報。在這份綜合指南中,我們旨在揭開與iPhone使用相關的一些最常遇到的挑戰的神秘面紗。我們的逐步方法旨在幫助您解決這些常見問題,提供實用的解決方案和故障排除技巧,讓您的裝置恢復到最佳工作狀態。無論您是面對一個小故障還是更複雜的問題,本文都可以幫助您有效地解決這些問題。一般故障排除提示在深入研究具體的故障排除步驟之前,以下是一些有助於

《掌握Linuxread指令的基本功能與操作技巧》在Linux系統中,read指令是一個非常有用的指令,用來從標準輸入中讀取資料。透過read指令,使用者可以互動式地輸入數據,或將數據儲存到變數中進行後續處理。在本文中,我們將深入探討read指令的基本功能和操作技巧,同時提供具體的程式碼範例來幫助讀者更好地理解並運用這個指令。 read指令的基本用法read命

解決jQuery.val()無法使用的問題,需要具體程式碼範例對於前端開發者,使用jQuery是常見的操作之一。其中,使用.val()方法來取得或設定表單元素的值是非常常見的操作。然而,在一些特定的情況下,可能會出現無法使用.val()方法的問題。本文將介紹一些常見的情況以及解決方案,並提供具體的程式碼範例。問題描述在使用jQuery開發前端頁面時,有時候會碰

弱監督學習中的標籤獲取問題,需要具體程式碼範例引言:弱監督學習是一種利用弱標籤進行訓練的機器學習方法。與傳統的監督學習不同,弱監督學習只需利用較少的標籤來訓練模型,而不是每個樣本都需要有準確的標籤。然而,在弱監督學習中,如何從弱標籤中準確地獲取有用的信息是一個關鍵問題。本文將介紹弱監督學習中的標籤獲取問題,並給出具體的程式碼範例。弱監督學習中的標籤獲取問題簡介:

【如何使用Linuxread指令讀取檔案內容】在Linux系統中,read是用來從標準輸入或檔案讀取資料的指令。使用read指令可以幫助使用者快速取得文件內容,並進行後續的處理。以下將詳細介紹如何使用Linuxread指令讀取檔案內容,包括具體的程式碼範例。讀取檔案內容要讀取檔案內容,首先需要開啟終端,並使用以下命令格式來讀取檔案內容:read[-

機器學習模型的泛化能力問題,需要具體程式碼範例隨著機器學習的發展和應用越來越廣泛,人們越來越關注機器學習模型的泛化能力問題。泛化能力指的是機器學習模型對未標記資料的預測能力,也可以理解為模型在真實世界中的適應能力。一個好的機器學習模型應該具有較高的泛化能力,能夠對新的數據做出準確的預測。然而,在實際應用中,我們經常會遇到模型在訓練集上表現良好,但在測試集或真實
