MySQL引擎、锁以及MVCC关系梳理

    最近又陆陆续续学了些MySQL的底层原理,感觉数据库真的是开发中异常高深玄妙的东西。毕竟作为最底层的存储结构,数据库的安全和稳定对整个系统的稳定运行起到着至关重要的作用。
    每次学习数据库的相关知识的时候,都觉得会有新的收获和感悟,从零零散散的知识点,逐渐能够拼凑起一个简单的结构,因此打算简单梳理一下自己最近所学与所获。
    数据库较为重要的知识包括引擎、事务、索引、锁等等,对于这些内容的相关介绍可以从各个博客和视频中看到,因此就不详细介绍了,这里主要想梳理一下不同引擎下的区别和联系,主要是MyISAM和InnoDB引擎。

1.MyISAM引擎

1.1 索引机制

    在这里默认索引的数据结构采用B+tree,在MyISAM引擎中,索引和数据是分离的,也就是说,索引文件仅仅用来记录数据在数据文件中的地址,这种方式被成为非聚集索引
在这里插入图片描述

1.2 锁机制

    在MyISAM引擎中,不存在行锁、间隙锁等开销较大的锁,该引擎下仅支持表锁,即如果想要加锁,只能把整个表全部锁住。
    当然,表锁也区分读锁(共享锁)和写锁(排他锁)。对于一个加了读锁或写锁的事务,他的权限如下所述(不仅适用于表锁,也适用于行锁):

事务A加读锁
事务A只能读加锁数据,既不能读其他数据,也不能改加锁数据;
其他事务可以读加锁数据,也能读其他数据,但是不能改加锁数据。
事务A加写锁
事务A既可以读加锁数据,也可以写加锁数据,但是无法读写其他数据;
其他事务不能读加锁数据,如果想要写加锁数据,将会进入阻塞状态,直到锁被事务A释放。

在数据库中,可能发生的并发操作包括读读、读写、写写,其中,多事务的读读操作不会造成数据上的问题,而读写和写写如果处理不好,则容易发生数据不同步、数据丢失等严重的问题,而锁正是为了解决写写问题

2.InnoDB引擎

1.1 索引机制

    与MyISAM不同,InnoDB引擎的数据存储本身就是一个索引,它与上图的区别在于,B+tree的叶子节点中存储的就是数据本身,而非地址,这种方式叫做聚集索引。一般来说,被作为索引的值一般主键,如果不设置主键的话,系统会自动为每一行添加一个隐形的自增序列号作为索引值,自增主要是考虑到B+tree的数据结构,防止插入时造成过多的节点分裂。
在这里插入图片描述
    除了主键索引外,InnoDB引擎还包括普通索引,即基于普通字段或复合多个字段建立的索引,这种索引也是采用B+tree,但是他的叶子节点存储的是主键或自增序列号,即当我们通过普通索引查到主键之后,还要再到主键索引中再次进行一次查询,即二次索引
    当然,索引不是始终生效的,在某些查询条件下,索引将不再生效,而是采用全表扫描的方式,具体可以参考这篇博客,介绍了索引失效的情况。所以,在进行sql查询的时候,sql语句的书写方式也会影响查询的效率。

1.2 事务

    需要注意的是,MyISAM引擎是不支持事务的,我们所说的事务通常是InnoDB引擎下的事务,至于事务的特性,隔离级别,就不在这里赘述啦,这类博客遍地开花,比如可以参考这篇。

1.3 锁机制

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。
    行锁的引入减小的锁的粒度,但是增大的系统的开销,不过在写操作比较多、而且高并发的场景下,这种开销是值得的。
    行锁同样包括读锁和写锁,其特性已经在前文进行描述。
    但是特别需要注意的是,只有在查询中走索引的情况下,行锁才会生效,如果某个事务在进行某项操作时,索引没有生效,而是采用的全表扫描的方式,那么行锁将会升级为表锁,这样将极大的影响数据库的运行效率。因此,通过锁机制也可以看出,数据库索引的重要性。这篇文章介绍了几个行锁变表锁的实例。
    总之,行锁与索引是紧密联系的,这同样也突出了建立索引和SQL语句优化的重要性。

1.4 MVCC机制

    前面介绍的锁主要是为了避免写写问题,虽然锁也可以解决读写问题,但是这样会显著地降低数据库效率。InnoDB引擎的MVCC机制则是为了通过不加锁的方式来解决不同事务间的读写问题
    对于读写问题,主要包括以下几点,同样也是事务不同隔离级别所要解决的问题:

脏读
不可重复读
幻读

    虽然我们在学习数据库事务的时候,经常接触到这几个字眼,但仔细分析你会发现,这些问题的出现都有同样的特征:一个事务在对数据进行查询,另外的事务在对同样的数据进行修改。这刚好反应的就是读写问题。而MVCC的出现就是为了解决脏读、不可重复读的问题,同时也可以解决部分幻读问题。
    关于MVCC的底层原理,博客上面很多介绍都是错误的。其实现过程主要是隐藏字段+ReadView+Undo Log。经过比较和浏览,我看到一篇介绍很好的博客和一段视频,如果想要学习的话可以参考博客和视频来进行学习。博客地址在这里,视频地址在这里。

    总之,随着不断地学习,也逐渐了解了越来越多数据库的奥秘,发现数据库真是一门学无止境的宝藏。或者随着未来自己对知识理解的深入,又能有更多更不一样的收获。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值