1.innodb索引

innodb是页存储,一页是16K。

一个表的行数据都放到页里,单页都是单链表递增排序。

每个页之间都是双向链表保存。该页标记成数据页。

根据id查询时,也不知道在哪个数据页上。

因此会对数据页建立一个索引,每一个索引值的内容是数据页id,以及每一个数据页最小的id。通过二分就很容易定位到数据页。

当然,这个索引页也是16K,当数据足够多,也会进行索引页分类。

所以当索引页变多后,上面也会在建立一层索引页。

一页16*1024=16284字节

假设一个表的字段 8(bigint)+3(int)*3+8*2(timestamp)+3(utf8汉字)*20(长度)=93字节 已经很多大了。

平均一页有150条数据。

但是索引页的数据页号+索引最小值也就16字节。一页大概有1000条数据

那三层结构的树,就能支撑 150*1000*1000=1.5亿条数据。

所以一般三层的B+树就够了。也就进行三次磁盘IO,读取三次数据页。

//redo log的作用

mysql是先写日志在写数据。由于mysql使用内存buffer,并且一条sql修改的数据,会修改很多数据页,尤其是索引多的情况。并且这些数据页都是随机读取,数据很慢,因此mysql不会为很小的一次改动,就把这么多的数据页写到磁盘上。但是只写内存,服务器宕机会导致数据丢失,因此会记录redo log。这个log是磁盘顺序写,速度比较快。这就是redo日志的作用。

为什么使用B+树而不是B树

我们注意到,innodb的数据的索引模式,很像一颗树。一层层构建索引。

同时这种数据结构,数据也必须放到叶子节点上。这也是最契合需求的数据结构。

如果像B树一样,把数据放到节点上,那每一个页的能放的数据就很少,这样树的层数必然更深。从上面的分析中就可发现,150*1000*1000 随着表字段或者内容的增多,叶子页的能容纳的数据会越来越少,不过索引页里放的都是页号和索引值的最小值,这样必然索引的B+树不会超过4层就可满足数据要求。

同时B+的叶子节点之间是个链表,这样范围查找时,只需要对叶子节点进行遍历即可。

B树会把索引值和数据都在节点上,这样做范围查找时,必然要进行回溯或者多次查找。

索引

主键索引上有数据信息,因此称为聚簇索引。

其余页的索引,就是把内节点的主键最小值替换成索引列对应最小值即可。同时叶子节点存放的是索引列和主键ID的信息,因此需要再次回表查询。这种列索引称为二级索引或者辅助索引。

联合索引,就是一个内节点或者叶子节点上,有两个值。

这也解释了为啥遵循最左原则,毕竟联合索引的排序,是先比较第一个值,在比较第二个值。

2.mvcc

首先提下mysql的四种隔离级别

读未提交

读已提交

可重复读

串行

读未提交直接读取数据最新的数据就行(包括未提交的事务)。串行使用锁就行可。

所有mvcc也仅对读已提交和可重复读这两个隔离级别下的

事务中的update操作,会在聚簇索引和undo日志的 poll_pointer属性,构成一个记录的版本链。

ReadView

在上面两种隔离级别下,发生读操作时,会在不同时机生成ReadView。

其中的4个重要的内容

m_ids 生成ReadView时,活跃的(未提交的)事务id

min_trx_id 生成ReadView时,活跃的事务中,最小的事务id

max_trx_id 生成ReadView时,系统应该分配给下一个事务的id(事务id是连续递增的,注意,这里不是活跃id的最大值!!!)

creator_trx_id 生成该ReadView的事务id

有了ReadView后,在访问某条记录时,会遍历它的版本链,发现可以读到的数据。

1.如果被访问的trx_id跟ReadView的creator_trx_id一致的话,意味着当前事务访问它自己修改的记录,所以该版本可以被当前事务访问。

2.如果被访问版本的trx_id小于ReadView的min_trx_id,表示这个版本在生成ReadView之前已经提交,可以被访问。

3.如果被访问版本的trx_id大于max_trx_id,表示生成该版本的事务在当前事务ReadView生成之后开启,所以该版本也不被访问。

4.如果在min和max之间,并且在m_ids中,则不能被访问,反之说明该版本对应的事务已经结束,是可以访问的。

看完上面ReadView可见的规则后,一般都会有些迷茫的。尤其是4的规则。结合下面两种不同隔离级别下ReadView生成的时机,你就理解上面ReadView的设计了

读已提交级别

该级别规定只能读取已提交的,所以ReadView中m_ids表示正在活跃事务,也就是没有提交的事务,所以不能读取。哈哈,看到这,是不是对4理解了。活跃的事务不可读。

所以一次事务中多次读,每次都生成ReadView,检查对应的数据版本即可。

可重复读

该隔离级别要求 一次事务多同一条数据的读取,每次都得一样。因此每次都使用第一次读创建的ReadView即可。这样每次读的内容都一样了。

所以这里对ReadView是一种复用,这两种隔离级别的区别是ReadView的生成时机不一样。

二级索引与MVCC

前面说的都是聚簇索引的MVCC。

二级索引页的Page Header中有一个PAGE_MAX_TRX_ID的属性,当页面进行写操作时,发现页面的该值小于当前事务ID,直接将事务ID设置为页面的PAGE_MAX_TRX_ID。

如果读事务的ReadView的min_trx_id大于页面的最大事务id,那么该页数据都可被查看。如果小于,只需要进行回表之后,在进行可见性判断。

根据二级索引的主键id后,得到对应的聚簇索引记录后,在按照之前的逻辑进行查看。(还记得之前提到undo log里,如果没有修改的字段,log里没有,这里还需要对链表进行查询,找到该字段的最新值)

3.锁

锁模式

S锁 X锁,意向S锁,意向X锁

锁类型

LOCK_GAP

也就是间隙锁,它锁住的是某条记录之前的位置。

例如有两条主键为3和8的两条记录,3-8之间没有记录,当在8上加了间隙锁,那么其他事物,是不允许往3-8之间写数据了。

LOCK_REC_NOT_GAP单独加到一条记录上

LOCK_ORDINARY GAP和记录锁的合体,也是next-key锁

select for update是加X锁

表级锁 每个行级锁,都有对应IS,IX意向锁加到表上。

mysql加锁的方式太多,遇到死锁,可以根据死锁日志去看加锁的状态。

mysql b 树 锁_mysql索引B+树、MVCC、锁一文搞懂相关推荐

  1. mysql设置索引树长度_MySQL索引-B+树

    索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据. 索引最形象的比喻就是图书的目录了.注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 ...

  2. 什么是MVCC,一文搞懂MySQL的MVCC机制

    MVCC是什么 MVCC,即Multi-Version Concurrency Control (多版本并发控制).它是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中 ...

  3. mysql行锁索引问题_Mysql锁机制--索引失效导致行锁变表锁

    =============== Tips:在阅读本文前,最好先阅读 这篇(Mysql锁机制--行锁)文章~ 在上篇文章中,我们看到InnoDB默认的行锁可以使得操作不同行时不会产生相互影响.不会阻塞, ...

  4. 深度解析串行并发并行,开发人员需彻底搞懂丨mysql|redis|skynet|协程|索引|读写分离|分布式锁|主从同步

    深度解析串行并发并行,开发人员需彻底搞懂 视频讲解如下,点击观看: 深度解析串行并发并行,开发人员需彻底搞懂丨mysql|redis|skynet|协程|索引|读写分离|分布式锁|主从同步丨C/C++ ...

  5. 一文搞懂 MySQL 索引

    一文搞懂 MySQL 索引 1.MySQL 索引 简介 1.1.MySQL 索引 是什么?  索引是一个单独的.存储在 磁盘 上的 数据库结构 ,包含着对数据表里 所有记录的 引用指针. 1.2. M ...

  6. 丁奇mysql45讲百度云下载_MySQL实战45讲,丁奇带你搞懂MySQL【完结】

    开篇词.这一次,让我们一起来搞懂MySQL.mp3 开篇词.这一次,让我们一起来搞懂MySQL.pdf 01.基础架构:一条SQL查询语句是如何执行的?.mp3 01.基础架构:一条SQL查询语句是如 ...

  7. 一文搞懂MySQL数据库分库分表

    如果数据量过大,大家一般会分库分表.分库需要注意的内容比较少,但分表需要注意的内容就多了. 工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过 ...

  8. 一文搞懂Elasticsearch索引的mapping与setting

    目录 Elasticsearch索引结构 Mapping Setting Elasticsearch索引结构 一个Elasticsearch索引的主要结构如下: {"test_index&q ...

  9. 一文搞懂MySQL XA如何实现分布式事务

    一文搞懂MySQL XA如何实现分布式事务 前言 XA 协议 如何通过MySQL XA实现分布式事务 前言 MySQL支持单机事务的良好表现毋庸置疑,那么在分布式系统中,涉及多个节点,MySQL又是如 ...

最新文章

  1. html(超链接定义锚点与特殊符号转义)
  2. MySQL--使用innodb_force_recovery修复数据库异常
  3. Shiro <shiro:hasPermission >标签不生效,shiro权限不生效原因
  4. 从新手到Flutter架构师,一篇就够!学习路线+知识点梳理
  5. 企业实战05:Oracle数据库_操作表中数据
  6. slot传函数 vue_面试必备 Vue 知识点
  7. 来谈谈MySQL事务及事务引发的问题
  8. OpenShift 4 之Istio-Tutorial (4) 流量控制和灰度发布
  9. 老罗Android开发视频教程
  10. 新手入门 | 算法书籍推荐
  11. JL杰理 蓝牙音箱 蓝牙耳机 方案 找个有经验的兄弟
  12. 手机卡顿怎么办?学会这三个方法清理内存,手机多用三年都不卡
  13. 电脑基础知识入门:键盘上的英文,意思和功能汇总!
  14. Zabbix Database error
  15. .fit VS .fit_generator in Keras
  16. 一篇工作调动时的旧文
  17. K8s基础入门及实战
  18. php限定符实例,PHP正则表达式限定符说明
  19. msconfig打不开,运行找不到msconfig解决办法
  20. 九度OJ 1183:守形数 (数字特性)

热门文章

  1. vi 不保存退出_vi / vim编辑器介绍
  2. 为什么envi镶嵌老是出错_10个数学考试老出错的根源和解决办法,你值得拥有
  3. java true false_关于java:如何存储boolean返回false / true的次数
  4. win10你的电脑设备需要修复_图文详解win10升级失败的解决方法
  5. openGL与openGL ES 的区别
  6. 集成Tomcat环境到Eclipse中
  7. [ARC057D]全域木
  8. 高并发编程-07-JDK提供的原子类操作及原理
  9. C#编写程序操作数据库如何防止SQL注入漏洞的发生
  10. web服务器压力测试工具