mysql innodb高并发基础-MVCC

mysql innodb能高效运行,支撑高并发原因就是基于MVCC实现。

本文仅是简单介绍下MVCC原理,介绍事务隔离级别RC,RR中原理。

MVCC

MVCC(全称Multi-Version Concurrency Control),多版本并发控制,解决数据库的并发访问高效问题。

维基百科中有更具体的描述,感兴趣可以看看。

MVCC到底解决什么问题

数据库中,读数据的同时,有另外的任务写入数据,在没有任何锁机制情况下,很有可能读到是『半写』或者不一致的数据。

当然解决这个问题最简单的方法,通过加锁,即Share lock,write lock,会有读读兼容,读写或写读阻塞问题,这种方式效率很低。实际中,在写某行数据同时,又另外任务使用mysql同时去读数据,读操作并没有感受到block,反而觉得效率很高。可以确定是mysql中没有最简单的机制来保证并发,官方文档上申明使用了MVCC。

当然,innodb是行锁,针对记录的更新会加排他锁,保证并发时资源时线程安全。
锁的介绍博文中有介绍,这里就不多介绍。

MVCC是怎么做到的

mysql文档:InnoDB是一个多版本的存储引擎,保存有关行已更改的old version的信息,以支持并发和回滚等事务功能。

简而言之:

MVCC使用了快照手段,每个连接到数据库的读者,在某个瞬间看到的是数据库的 某一个快照,写者写操作造成的变化在写操作完成之前(或者数据库事务提交之前)对于其他的读者来说是不可见的。

内部,InnoDB为数据库中存储的每一行j记录添加三个字段:

  • 6字节的事务ID(DB_TRX_ID ):表示插入或更新该行的最后一个事务的事务标识符
  • 7字节的回滚指针(DB_ROLL_PTR):指向写入回滚段的undo log记录。更新了行,则undo log记录包含在更新行之前重建行内容所需的信息。
  • 6字节的自增 (DB_ROW_ID):插入新行时单调增加的行ID。

undo log

回滚使用undo log,以rollback segment的数据结构(Oracle也是类似数据结构)为单位进行存储,存储在表空间中,可以说undo log被划分为多个段,具体某行的undo log就保存在某个段中 。因此InnoDB使用回滚段中的信息来执行事务回滚中所需的undo操作。磁盘上不存在单独的undo log文件,所有的undo log存放在存放于ibdata文件中。

具体操作:copy事务前的数据库内容(行)到undo buffer,在适合的时间把undo buffer中的内容刷新到磁盘。undo buffer是环形缓冲,但当缓冲满的时候,undo buffer中的内容会也会被刷新到磁盘undo log文件,所有的undo log均存放在主ibdata文件中(表空间),即使客户端设置了每表一个数据文件也是如此。

undo log分为insert 和update undo log类型,删除也是update undo log。

insert undo log:原始的数据并不存在,所以回滚时把insert undo log丢弃即可

流程如下

  1. 初始数据行


    image.png

    原始的数据并不存在,回滚指针是null,回滚时直接丢弃改行。

  2. 事务1更修改
    获得记录更新锁后,把该行修改前的值Copy到undo log,记录事务ID 回滚ID。

image.png

3.事务2修改


image.png
  1. 事务提交
    当事务正常提交时,只需要更改事务状态为COMMIT即可,不需做其他额外的工作,而Rollback则稍微复杂点,需要根据当前回滚指针从undo log中找出事务修改前的版本并恢复。

上面的流程看来,undo log是不是越来越大,这点mysql也做了考虑,会启动purge进程以真实删除老的、过时的数据。

redo log

为了支持事务使用redo log。当客户端执行每条SQL(更新语句)时,redo log会被首先写入log buffer,执行COMMIT命令时,log buffer中的内容会被视情况刷新到磁盘。具体作用:保存执行的SQL语句到一个指定的Log文件,当Mysql服务因断电恢复或强行重启等时重新执行redo log记录的SQL操作,继续那些已经commit但数据尚未完全回写到磁盘的事务,保证操作不丢失。

与事务关系

  • READ_UNCOMMITTED
    读事务直接读取主记录,无论更新事务是否完成。

  • READ_COMMITTED
    优先读取本事务修改的值,未有修改的每次都读取undo log中最近的版本。两次对同一字段的读可能读到不同的数据,但能保证每次都读到最新的数据。使用行锁。

  • REPEATABLE_READ
    读该事务第一次读建立起来的数据快照,每次都读取指定的版本,如果没有做更新可能读不到最新的数据。这里使用行锁,gap锁,next-key锁,如果索引不是聚镞索引,使用next-key锁能保证不会产生幻读。

  • SERIALIZABLE
    读加共享锁,写加排他锁,读读不会阻塞,读写或写读出现阻塞,因此并发度大幅下降。

参考资料

https://en.wikipedia.org/wiki/Multiversion_concurrency_control
https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html
http://www.360doc.cn/article/12904276_403505950.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352