当前位置: 首页 > news >正文

南昌网站建设700起seo优化一般包括

南昌网站建设700起,seo优化一般包括,电子商务网站建设规划,百度自动驾驶技术MVCC机制解析:提升数据库并发性能的关键 MVCC(Multi-Version Concurrency Control) 多版本并发控制 。 MVCC只在事务隔离级别为读已提交(Read Committed)和可重复读(Repeated Read)下生效。 MVCC是做什么用的 MVCC是为了处理 可重复读 和…

MVCC机制解析:提升数据库并发性能的关键

MVCC(Multi-Version Concurrency Control) 多版本并发控制

MVCC只在事务隔离级别为读已提交(Read Committed)和可重复读(Repeated Read)下生效。

MVCC是做什么用的

MVCC是为了处理 可重复读读已提交 事务隔离级别下,在同一事务里,多次执行同一SQL查询语句,不会因为其他事务的横插一脚,对数据进行修改后,导致最终得到的结果不一致。如下图所示,事务B的两次查询得到的结果不一样。

请添加图片描述

MVCC是怎么实现的

串行读 这一事务隔离级别里面,为了保证较高的事务隔离性,采用了将所有的操作加锁互斥,将事务的执行变为顺序执行,相当于单线程的方式,以达到其高隔离性。

而mysql在 可重复读已提交读 事务隔离级别下,他的隔离性是借助MVCC机制来保证的,MVCC机制呢,也不是通过加锁互斥来保证隔离性的,是通过 Undo日志版本链Read View机制 实现的。避免了频繁的加锁互斥阻塞。

Undo日志版本链

Undo日志是什么?

undo日志是回滚日志,在mysql对某一数据进行修改更新时,会将其更新前的数据保存的undo回滚日志里,等当事务执行失败时,用来进行数据回滚的。

而什么是undo日志版本链呢?

就是一行数据被多个事务依次修改后,这条数据就会有很多条undo日志,这些undo日志就会通过一个 roll_pointer 字段进行串联起来,会形成这条数据的历史记录版本链,这个就是undo日志版本链。

roll_pointer 字段哪里来的呢?

在mysql数据库里,数据表都会有两个隐藏的字段属性, trx_id事务idroll_pointer回滚指针 ,其中 trx_id 是用来记录操作数据的,而 roll_pointer 则是用来记录指向上一次修改的日志地址。

注意:begin/start transaction这个开始/启动事务命令,并不是一个事务的起点, 而是在执行到第一条更新update、删除delete、插入insert语句时,事务才真正的启动,才会有真正的事务id。

后生成的trx_id要比先生成的trx_id大。

只有InnoDB数据引擎才支持事务。

下图中,每一条数据都是一个undo回滚日志,通过roll_pointer串联起来后,就是undo日志版本链了。

请添加图片描述

如果第二次修改操作将name改为了 王五 ,又因为某些原因需要进行数据回滚,就要拿到roll_pointer里记录的上一次,也就是第一次修改操作的undo回滚日志地址,将name回滚为 赵六

Read View机制

在可重复读隔离级别下,一个事务在开始时,执行任何的查询SQL脚本,都会生成一个属于当前事务自己的 Read View一致性视图 ,这个视图在这个事务结束之间,都是保持不变的(除非在本事务里面自己执行了更新操作)。

如果事务隔离级别是读已提交,则 Read View一致性视图 是在每次执行查询SQL脚本时,都会重新生成,与可重复读隔离级别的在同一事务里保持不变不同。

这个视图是什么呢?

这个视图是由执行查询SQL脚本这一时刻,所有还未提交的事务id构建而成的数组,和此时存在最大的一个事务id共同构建而成。

示意图一

请添加图片描述

示意图二

请添加图片描述

结合上面两图分析可知,

事务A 第一次执行查询语句时刻,所生成的ReadView的构成为 {[1002,1003,1004], 1004} ,其中[1002,1003,1004]为未提交的事务id(min_id=1002,min_id最小事务id是从未提交事务id里获取的),1004为当前最大的事务id(max_id=1004)。

事务A 第二次、三次执行查询语句时刻,其ReadView的依旧为 {[1002,1003,1004], 1004}

事务B 第一次执行查询语句时刻,所生成的ReadView的构成为 {[1002,1004], 1004} ,其中[1002,1004]为未提交的事务id(min_id=1002),1004为当前最大的事务id(max_id=1004)。

事务B 第二次执行查询语句时刻,所生成的ReadView的依旧为 {[1002,1004], 1004}

根据事务A和事务B的ReadView可以得出一个相同的工具图(用来判断某事务的某一次数据更新,是否对select是可见的)

事务里的select语句查询结果都是需要从undo日志版本链最新数据开始,逐条与本事务的ReadView进行比对,判断应该获取到哪一日志版本的数据为select语句的查询结果。

示意图三

请添加图片描述

比对规则

  • 如果比较的undo日志的 trx_id小于min_id ,则表示这个版本事务是已经提交的,代表本次select这一事务可以查到这个数据。

  • 如果比较的undo日志的 trx_id大于max_id ,则表示这个版本事务是在本次select这一事务后面新启动的,这种数据肯定是不可被查询到的。

  • 如果比较的undo日志的 trx_id大于等于min_id ,且 trx_id小于等于max_id ,则再判断 trx_id是否是在未提交事务id数组里。

    • 在未提交事务id数组里,则表示这个版本数据是由未提交的事务所生成的,这种数据不可被查询到(除非这个未提交的事务就是自己)。
    • 不在未提交事务id数组里,则表示这个版本数据是由已经提交的事务所生成的,这种数据可以被查询到。

案例一

那么事务A第一条select语句查询脚本执行时,获取到的name是什么呢?

先说结果,查询到的name为赵六。

事务A执行第一条select语句时,他的SQL执行顺序,和SQL查询脚本执行时拿到的日志版本链及判断示意图如下。

请添加图片描述

请添加图片描述

上面在示意图二里也说了,事务A的第一次执行查询语句时刻时,其ReadView为 {[1002,1003,1004], 1004}

请添加图片描述

比较步骤如下

第一次: 事务A从undo日志版本链拿到最后一次更新记录(第二次修改记录),得到trx_id为1003,然后对照着上面的 判断工具图 进行比较,大于min_id,小于max_id,所以1003事务id属于是 第二部分 ,且1003这一事务id处于还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1003,1004]),所以这个事务进行的更新数据,是不可被查询到的。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第二次: 事务A从undo日志版本链拿到第二条日志记录(第一次插入记录),得到trx_id为1001,然后同样对照着上面的 判断工具图 进行比较,发现小于min_id的1002,所以1001事务id属于是 第一部分 ,是已经提交了事务的,他更新的数据就属于可以被查询到,于是此时查询到的结果name为张三。

案例二

那么事务A第二条select语句查询脚本执行时,获取到的name是什么呢?

先说结果,查询到的name依旧为赵六。

事务A执行第二条select语句时,他的SQL执行顺序,和SQL查询脚本执行时拿到的日志版本链及判断示意图如下。

请添加图片描述

请添加图片描述

上面在示意图二里也说了,事务A的第二次和第三次执行查询语句时刻时,其ReadView依旧为 {[1002,1003,1004], 1004}

请添加图片描述

比较步骤如下

第一次: 事务A从undo日志版本链拿到最后一次更新记录(第四次修改记录),得到trx_id为1003,然后对照着上面的 判断工具图 进行比较,大于min_id,小于max_id,所以1003事务id属于是 第二部分 ,继续判断得知,1003这一事务id处于还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1003,1004])(即便此时事务1003已经提交了,但是只要在事务A第一次执行查询语句时,这个事务没有提交,那他在事务A里就一直被标记的是未提交,否则就会出现 不可重复读 问题),所以这个事务进行的更新数据,是不可被查询到的。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第二次: 事务A从undo日志版本链拿到第二条日志记录(第三次修改记录),得到trx_id为1002,然后同样对照着上面的 判断工具图 进行比较,发现等于min_id的1002,所以1002事务id属于是 第二部分 ,继续判断得知,1002这一事务id处于还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1003,1004]),所以这个事务进行的更新数据,是不可被查询到的。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第三次: 事务A从undo日志版本链拿到最后一次更新记录(第二次修改记录),得到trx_id为1003,然后对照着上面的 判断工具图 进行比较,大于min_id,小于max_id,所以1003事务id属于是 第二部分 ,且1003这一事务id处于还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1003,1004]),所以这个事务进行的更新数据,是不可被查询到的。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第四次: 事务A从undo日志版本链拿到第二条日志记录(第一次插入记录),得到trx_id为1001,然后同样对照着上面的 判断工具图 进行比较,发现小于min_id的1002,所以1001事务id属于是 第一部分 ,是已经提交了事务的,他更新的数据就属于可以被查询到,于是此时查询到的结果name为张三。

案例三

那么事务B第一条select语句查询脚本执行时,获取到的name是什么呢?

先说结果,查询到的name为李四。

为什么事务B的一条查询语句和事务A的第二条查询语句是同时执行的,但是结果不一样呢?可以详细看看下面对事务的比较步骤。

事务B 第一次执行查询语句时刻,其所生成的ReadView的构成为 {[1002,1004], 1004} ,其中[1002,1004]为未提交的事务id(min_id=1002),1004为当前最大的事务id(max_id=1004)。

事务B执行第一条select语句时,他的SQL执行顺序,和SQL查询脚本执行时拿到的日志版本链及判断示意图同案例二里的一样。

比较步骤如下

第一次: 事务B从undo日志版本链拿到最后一次更新记录(第四次修改记录),得到trx_id为1003,然后对照着上面的 案例二的判断工具图 进行比较,大于min_id,小于max_id,所以1003事务id属于是 第二部分 ,继续判断得知,1003这一事务id 不处于 还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1004]),所以表示这个事务已经提交了,这个事务所更新的数据版本可以被查询到,查询结果就是name为李四。

案例四

事务A第三条select语句查询脚本执行时,获取到的name是什么呢?

先说结果,查询到的name还是赵六。

事务A执行第三条select语句时,他的SQL执行顺序,和SQL查询脚本执行时拿到的日志版本链及判断示意图如下。

请添加图片描述

请添加图片描述

上面在示意图二里也说了,事务A的第二次和第三次执行查询语句时刻时,其ReadView依旧为 {[1002,1003,1004], 1004}

请添加图片描述

比较步骤如下

第一次: 事务A从undo日志版本链拿到最后一次更新记录(第五次修改记录),得到trx_id为1004,然后对照着上面的 判断工具图 进行比较,大于min_id,小于 等于 max_id,所以1004事务id属于是 第二部分 ,且1004这一事务id 不处于 还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1003,1004]),所以这个事务进行的更新数据,是不可被查询到的。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第二次: 比较过程和示例二里的第一次比较操作过程一样。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第三次: 比较过程和示例二里的第二次比较操作过程一样。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第四次: 比较过程和示例二里的第三次比较操作过程一样。

于是根据roll_pinter回滚指针(上一版本数据的地址)找到上一个版本数据。

第五次: 比较过程和示例二里的第四次比较操作过程一样。得到查询结果name为张三。

案例五

那么事务B第二条select语句查询脚本执行时,获取到的name是什么呢?

先说结果,查询到的name为李四。

事务B 第二次执行查询语句时刻,其所生成的ReadView的依旧为 {[1002,1004], 1004} 。和其第一次执行查询语句时刻一样。

事务B执行第三条select语句时,他的SQL执行顺序图,和SQL查询脚本执行时拿到的日志版本链和上面案例三的一样。

虽然ReadView和案例三的不同,为 {[1002,1004], 1004} ,但是其形成的判断图还是一样的。

请添加图片描述

比较步骤如下

第一次: 事务B从undo日志版本链拿到最后一次更新记录(第五次修改记录),得到trx_id为1004,然后对照着上面的 判断工具图 进行比较,大于min_id,小于 等于 max_id,所以1004事务id属于是 第二部分 ,且1004这一事务id 不处于 还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1004])(即便此时事务1004已经提交了,但是只要在事务B第一次执行查询语句时,这个事务没有提交,那他在事务B里就一直被标记的是未提交,否则就会出现 不可重复读 问题),所以这个事务进行的更新数据,是不可被查询到的。(和上面案例二的第一次比较一样)

第二次:事务B从undo日志版本链拿到第二条日志记录(第四次修改记录),得到trx_id为1003,然后对照着上面的 案例二的判断工具图 进行比较,大于min_id,小于max_id,所以1003事务id属于是 第二部分 ,继续判断得知,1003这一事务id 不处于 还未提交的事务id构建而成的数组里(未提交的事务id数组[1002,1004]),所以表示这个事务已经提交了,这个事务所更新的数据版本可以被查询到,查询结果就是name为李四。

读已提交隔离级别又是怎么比较的

读已提交 (已提交读)事务隔离级别的undo日志版本链和 可重复读 是一样的,Read View的生成规则就不同了, 读已提交的 Read View一致性视图 是在每次执行查询SQL脚本时,都会重新生成 ,与可重复读隔离级别的在同一事务里保持不变的定义不同。

这也就导致每次执行查询脚本时,都会重新构建 还未提交的事务id数组 ,所以只要其他事务在本事务执行这一条查询脚本之前,更新数据并提交了,那他的更新数据就可以被本事务的这一次查询操作查询到。

其他的比对规则还是和 可重复读 事务隔离级别一样,仅仅是ReadView在每次查询时需要重新生成。

可以理解为 读已提交 事务隔离,只会读到最后一次提交了更新操作事务的数据。


文章转载自:
http://instanton.xnLj.cn
http://flounderingly.xnLj.cn
http://liposome.xnLj.cn
http://intellective.xnLj.cn
http://diviner.xnLj.cn
http://pearlite.xnLj.cn
http://reinvent.xnLj.cn
http://miscreance.xnLj.cn
http://wyoming.xnLj.cn
http://methodenstreit.xnLj.cn
http://exasperating.xnLj.cn
http://kindliness.xnLj.cn
http://equitableness.xnLj.cn
http://shabbiness.xnLj.cn
http://pincette.xnLj.cn
http://foyer.xnLj.cn
http://retinol.xnLj.cn
http://zooplastic.xnLj.cn
http://wildcatter.xnLj.cn
http://adiaphoretic.xnLj.cn
http://nogg.xnLj.cn
http://rimpled.xnLj.cn
http://chozrim.xnLj.cn
http://poetess.xnLj.cn
http://dermatophytosis.xnLj.cn
http://syndactylism.xnLj.cn
http://monistical.xnLj.cn
http://tamable.xnLj.cn
http://eradiculose.xnLj.cn
http://disincorporate.xnLj.cn
http://elliptoid.xnLj.cn
http://battlemented.xnLj.cn
http://enforcement.xnLj.cn
http://acknowiedged.xnLj.cn
http://wadset.xnLj.cn
http://railbus.xnLj.cn
http://leukemogenic.xnLj.cn
http://tongueless.xnLj.cn
http://presto.xnLj.cn
http://womanhood.xnLj.cn
http://necromancer.xnLj.cn
http://rawhide.xnLj.cn
http://pudding.xnLj.cn
http://tailgate.xnLj.cn
http://creeper.xnLj.cn
http://gardener.xnLj.cn
http://appositional.xnLj.cn
http://fraternization.xnLj.cn
http://ecotypic.xnLj.cn
http://inductee.xnLj.cn
http://superwater.xnLj.cn
http://thesaurus.xnLj.cn
http://peteman.xnLj.cn
http://tearstained.xnLj.cn
http://iffy.xnLj.cn
http://execrably.xnLj.cn
http://ctenophoran.xnLj.cn
http://petrification.xnLj.cn
http://runner.xnLj.cn
http://wakeless.xnLj.cn
http://flowerpot.xnLj.cn
http://interstock.xnLj.cn
http://metaphone.xnLj.cn
http://panther.xnLj.cn
http://mvo.xnLj.cn
http://pliohippus.xnLj.cn
http://exemplarily.xnLj.cn
http://mnemonist.xnLj.cn
http://appendix.xnLj.cn
http://overleap.xnLj.cn
http://barre.xnLj.cn
http://woodcarver.xnLj.cn
http://practice.xnLj.cn
http://multistage.xnLj.cn
http://boon.xnLj.cn
http://footmark.xnLj.cn
http://bora.xnLj.cn
http://odense.xnLj.cn
http://midships.xnLj.cn
http://sanction.xnLj.cn
http://materialize.xnLj.cn
http://assessor.xnLj.cn
http://directional.xnLj.cn
http://desmotropy.xnLj.cn
http://donative.xnLj.cn
http://epidemiology.xnLj.cn
http://clash.xnLj.cn
http://disembodiment.xnLj.cn
http://not.xnLj.cn
http://emulator.xnLj.cn
http://ganoin.xnLj.cn
http://panocha.xnLj.cn
http://insurmountable.xnLj.cn
http://lightsome.xnLj.cn
http://hydrolase.xnLj.cn
http://aerobiologic.xnLj.cn
http://overdrove.xnLj.cn
http://wormcast.xnLj.cn
http://coedition.xnLj.cn
http://ampleness.xnLj.cn
http://www.15wanjia.com/news/92178.html

相关文章:

  • 有哪些优秀的个人网站广东seo推广外包
  • 重庆点优建设网站公司吗上海高端网站定制
  • 5000人网站开发今日热点新闻事件及评论
  • 2020一建试题seo整站优化服务
  • 企业网站建设熊掌号西安seo网站推广优化
  • 生态旅游网站的建设合肥seo网络营销推广
  • 网站建设 模版选择中心免费推广途径与原因
  • 微平台推广是什么厦门seo专业培训学校
  • wordpress 方法标题优化seo
  • 四川微信网站建设网站自动秒收录工具
  • 最专业的医疗网站建设广西百度seo
  • 网站建设纳入本单位日常性工作谷歌广告投放教程
  • 用css3做酷炫网站个人做seo怎么赚钱
  • 国外优秀企业网站模板培训方案怎么做
  • 建设网站需要什么知识资讯门户类网站有哪些
  • 顺德网站建设教程seop
  • 长兴县网站建设怎么制作网页教程
  • 溧阳网站开发郑州百度seo网站优化
  • 如何创建自己的网站链接海外互联网推广平台
  • 网页设计作品我的家乡武汉网站营销seo方案
  • 实验室网站建设的调查报告西安百度推广联系方式
  • php网站开发说明文档五八精准恶意点击软件
  • 网站怎么优化关键词快速提升排名英文网站设计公司
  • 福建网站建设公司网站优化推广的方法
  • 网红营销论文seo索引擎优化
  • 用单页做网站 文章直接写上去 百度收录关键词吗足球联赛排名
  • 自己的网站怎么做app吗昆山网站制作哪家好
  • 网站建设金思扬网络如何用网站模板建站
  • wordpress下载站地推怎么做最有效
  • 制作网站的免费软件如何推广自己产品