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[-

机器学习模型的泛化能力问题,需要具体代码示例随着机器学习的发展和应用越来越广泛,人们越来越关注机器学习模型的泛化能力问题。泛化能力指的是机器学习模型对未标记数据的预测能力,也可以理解为模型在真实世界中的适应能力。一个好的机器学习模型应该具有较高的泛化能力,能够对新的数据做出准确的预测。然而,在实际应用中,我们经常会遇到模型在训练集上表现良好,但在测试集或真实
