MYSQL和InnoDB简述

1. 数据库和实例的区别和联系

区别
数据库:物理操作文件系统和其他形式文件类型的集合
实例:MYSQL数据库由中后台线程以及一个共享内存区组成

联系
数据库实例时数据库为上层提供的一个专门用于操作的接口

2. InnoDB

2.1数据的存储

所有的数据都被逻辑的放在表空间中,表空间是存储引擎中最高的逻辑存储单元,表空间下面分为:段、区、页
:表空间中的页大小默认是16kb,可以通过改变innodb_page_size选项对大小进行修改。
:最小是1MB,最少有64个页。

2.1.1 存储表

将表的定义和数据索引分开存储,前者存储在.frm中,后者存储在.idb中。

  • .frm文件
    包含了表结构的信息
  • .idb文件
    每一个表的单独空间,存储了当前表的数据和相关的索引数据

2.1.2 存储记录

使用页作为磁盘管理的最小单位,数据在Innodb按行储存,B-Tree节点是实际存放表中数据的页面。

2.1.3 数据页的结构

在这里插入图片描述
每一页包含两对头尾,页头和页尾记录的是页的状态信息,fil header和fil trailer记录的是页的头信息
infimum是最小值,supermum是最大值
user records是存放行记录,free space是空闲的时间。新来的信息从左往右插入节点,维护next_record指针,保持逻辑上的顺序。
B+树不会直接得到记录,而是找到相应的页,然后把页给内存,然后通过页尾存储的稀疏索引和n_owned、next_record取出相应的记录。

2.1.4 索引(非常重要)

B+数是平衡树,他查找任何一个节点的时间都是相同的,比较的次数就是B+的高度。
B+树索引可以分为聚集索引辅助索引,聚集索引存放着一条行记录的所有信息,辅助索引只包含索引列和一个用于查找行记录的书签。

  • 聚集索引
    按照主键的顺序构造一个B+树,并在叶节点中存放表中的行记录数据,使用聚集索引(主键)进行检索时,会直接获得行记录所在的页。
  • 辅助索引
    通过b+树实现,但是叶子节点不包含行记录的全部数据,仅包含索引中的所有键,和一个当前记录的主键,主要目的是查找主键。

3. 锁

乐观锁:其实是一种思想,先尝试对资源进行修改,在写回时,如果发生变化了就重新尝试,如果没有发生变化就写回,同时可以加一个version,需要较高的反应速度和并发量很大的情况。
悲观锁:在数据修改的时候直接加锁,表示现在只能自己写,其他线程阻塞。

3.1 行级锁

共享锁(读操作)和互斥锁(写操作)
并行读,串行写,互斥锁与其他任意的锁都是互斥的

3.2 表级锁

意向共享锁:事务想要得到表中某些记录的共享锁,需要在表上加上意向共享锁。
意向互斥锁:事务想要得到表中某些数据的互斥锁,需要在表上加上意向互斥锁。
如果对表中所有的数据进行修改,如过没有意向互斥锁,需要逐行进行判断,有了意向互斥锁,只需要等意向互斥锁释放就可以了。

3.3 记录锁

记录锁是加到索引记录上的锁。

  • 使用键作为where的过滤条件,InnoDB可以通过索引找到记录并添加记录锁。
  • 如果不是key作为过滤条件,InnoDB就不知道记录的位置,也无法对将要修改哪条记录提前做出判断就会锁定整个表。

3.4 间隙锁

间隙锁是对索引记录中的一段连续区域的锁,
使用select * from users where id between 10 and 15;的语句时,就会组织其他事务向表中插入id=15的记录,因为整个范围都被锁掉了。
虽然间隙锁也有共享锁和互斥锁,但是他们之间不是互斥的,不同的事务可以同时持有一段范围的间隙锁,唯一阻止的时向这一段区域插入数据。

3.5 Next-Key lock

Next-Key 锁是记录锁和间隙锁的结合。
Next-key锁锁定的是当前和前面的范围
假设锁定的范围如下:(-∞,21]、(21,30]、(30,40]、(40,50]…
如果更新一条记录:
seletct * from users where age=30 for update;
锁定的是(21,30]和(30,40]的记录都会被锁定
注:Next-key是为了解决幻读的。

3.6 死锁

两个事务都持有一个锁,并且尝试获取对方的锁就会发生死锁。

4. 隔离级别

未提交读:查询语句不会加锁,可能会读到未提交的行。(脏读)
提交读:只对记录加锁,不会加间隙锁,允许新的记录插入到被锁定的记录附近,使用多次查询的时候结果可能不一样。(非重复读)
可重复读:多次读取同一范围的数据,会返回第一次查询的数据,不会返回不同的数据行,可能会发生幻读。
串行化:隐式地将全部查询语句加共享锁,解决了幻读的问题。

MYSQL中默认的级别是可重复读,但是可以通过Next-key锁在某种程度上解决幻读的问题。
幻读:如下,第一次查是空,第二次查也是空,但是插入的时候错误了,说冲了,就感觉刚才出现的幻觉一样。可以加个Next-key解决,就是加个记录锁和间隙锁,或者使用串行化解决。
在这里插入图片描述

几种隔离度示意图:

  1. 未提交读(脏读):session1读到了session2的未提交数据。什么锁也没加。在这里插入图片描述
  2. 提交读(不可重复读):session1中查询一个范围,session修改了这个范围中的记录,并提交了,session1两次读取的不一样。本质是加了记录锁。
    在这里插入图片描述
  3. 可重复读(幻读):明明读取的没有,但是插入的时候显示重复了。本质上是记录锁+多次查询都是取第一次。 (可以加个Next-key解决)在这里插入图片描述
  4. 串行化:解决了幻读

参考文献:一篇文章带你读懂 Mysql 和 InnoDB

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值