目录

一、索引

索引是什么,页分裂

页的结构

mysql怎么查询数据

二、页合并

三、行溢出

四、事务

事务四大特性

1、原子性

2、一致性

3、隔离性

4、持久性

事务隔离级别

隔离级别导致的问题

隔离级别与锁的关系

锁与快照读、当前读的关系

RR快照读与RC快照读

MVCC机制——多版本并发控制机制

undo log

read view

举例


一、索引

图1

索引是什么,页分裂

MySQL b树与b+树,mysql索引等与数据的关系、命中多个索引走哪一个、为什么不建议is_del建索引_qq_41369135的博客-CSDN博客

页的结构

图2

mysql怎么查询数据

如在图1中查询id为10的数据,首先会找到页1,通过二分查找,定位到10在1-18之间。此时就找id=1的指针p1指向所在的第二层页2(为什么找1而不找18,是因为第一层的所有id指向的各自第二层页中都是最小的id,所以10必定在p1指针指向的页2,而不是p2指向的页3),再根据二分查找定位到10在页2的8-14之间,根据刚才的定理,10一定在8指向的页中。所以找到页6,注意。此时并不是直接去遍历user Record里的记录,而是去page directory二分查找,找到对应的槽位,遍历槽位之间的数据找到10(如user Record存放了1-100的数据,page directory存放的是[1,20,50,80,100],通过二分查找,得到10在1-20这个槽位。再遍历1-20找到10。)

二、页合并

InnoDB中的页合并与分裂 - 知乎

三、行溢出

Mysql之大字段溢出问题_jannals的博客-CSDN博客

四、事务

事务四大特性

1、原子性

事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只允许出现两种状态之一,要么都成功,要么都失败

任何一项操作都会导致整个事务的失败,同时其它已经被执行的操作都将被撤销并回滚,只有所有的操作全部成功,整个事务才算是成功完成

2、一致性

事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。

比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱

3、隔离性

事务的隔离性是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰。也就是说,不同的事务并发操作相同的数据时,每个事务都有各自完整的数据空间。

一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的

4、持久性

事务的持久性是指事务一旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态

在事物进行过程中,未结束之前,DML语句是不会更改底层数据,只是将历史操作记录一下,在内存中完成记录。只有在事物结束的时候,而且是成功的结束的时候,才会修改底层硬盘文件中的数据(这里就是指mysql刷盘机制了

事务隔离级别

读未提交:事务A能看到事务B修改但还没提交的数据。可能会导致脏读、不可重复度、幻读

读已提交:事务A只能看见事务B修改并提交事务后数据(解决了脏读,因为当事务B在对id=1的数据修改时,会对这行数据加排他锁,在事务B没提交之前,其他数据都不能读取该数据)。可能会导致不可重复读、幻读

可重复读:再事务A里多次读取到id=1的数据是一样的,不管其他事务这条数据进行了怎样的修改。可能会导致幻读

串行化:对于同一行记录,写会加“写锁”,读会加“读锁”,当出现锁冲突时,后访问的事务需要等前一个事务执行完成,才能继续执行。

隔离级别导致的问题

脏读:主要针对已存在的数据。举例场景(读未提交):事务A得到id=1的数据,并进行了修改。此时进来一个事务B,得到A修改后确没有提交事务的d=1的数据,并进行了其他操作,事务A报错回滚。那此时事务B读到的数据就是脏数据

不可重复读:主要针对已存在的数据。举例场景(读已提交):事务A得到id=1的数据,此时进来一个事务B,也得到id=1的数据,并进行修改,提交事务。此时数据库的真实数据已经被修改了。事务A再次查询id=1的数据,发现在同一个事务里(事务A)两次查询得到的数据不一致,导致该条数据不可重复读。同理:读未提交场景也是一样。

幻读:主要针对新增数据。举例场景(可重复读):幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:事务A查询某条记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在(因为事务B悄悄的插入了),无法插入,此时就发生了幻读。

隔离级别与锁的关系

mysql隔离级别与锁_像你这样的的博客-CSDN博客_mysql隔离级别与锁

锁与快照读、当前读的关系

S 锁与 X 锁,当前读与快照读! - 简书

RR快照读与RC快照读

因为我们在平时在写select查询语句时都是普通读,基本很少加锁(for update )。普通读在不同隔离级别就引出了两种读的方式:在RU与串行化是都是当前读(读取最新的),在RR与RC是快照读。但在RC中的快照读的效果确是相当于当前读(原因听下面的分解)

RR快照:业务层方法中第一次普通读(select查询)就会对当前查询记录生成快照,也只会生成一次快照。(注:update/insert/delete等语句虽然都有查询,但都是当前读不会生成readView)

RC快照:每此执行普通读都会生成新的快照

MVCC机制——多版本并发控制机制

  1. RC、RR里用到了MVCC机制,MVCC主要由undo log和read view实现
  2. 首先我们要清楚数据库的每条记录都有三个主要隐藏字段。row_id、trx_id、db_roll_ptr

row_id:当我们没有显示指定主键,那row_id就是数据库默认主键

trx_id:插入或更新这条记录时的事务id

db_roll_ptr:回滚时更新前的那条记录的地址,插入时,该条记录的这个字段为null,因为没得历史记录

undo log

undo log分成insert undolog和update undoLog(delete也算update undolog)

insert undolog:只有在回滚时需要。在事务提交完就删除(这个很好理解:比如事务A执行select普通查询,生成readview(快照),此时进来个事务B,事务B执行insert操作,并且commit提交,立马删除事务 B 该条记录的undolog。事务A再次执行select普通查询,如果是mysql是RC隔离级别,就会重新生成readView会把新插入的记录读取出来,如果是RR隔离级别,)

(原因下面readView讲完举例)

update undolog:回滚时和快照读都需要,事务提交后不能立马删,等待mysql的purge线程删。

(原因下面readView讲完举例)

历史数据再udno log里是什么样的?

图3

read view

我们先看看 ReadView 的几个重要属性

  • trx_ids: 当前系统中那些活跃(未提交)的读写事务ID, 它数据结构为一个List。(重点注意:这里的trx_ids中的活跃事务,不包括当前事务自己和已提交的事务,这点非常重要)

  • low_limit_id: 目前出现过的最大的事务ID+1,即下一个将被分配的事务ID。

  • up_limit_id: 活跃事务列表trx_ids中最小的事务ID,如果trx_ids为空,则up_limit_id 为 low_limit_id。

  • creator_trx_id: 表示生成该 ReadView 的事务的 事务id

访问某条记录的时候如何判断该记录是否可见,具体规则如下:

  • 如果被访问版本的 事务ID = creator_trx_id,那么表示当前事务访问的是自己修改过的记录,那么该版本对当前事务可见;
  • 如果被访问版本的 事务ID < up_limit_id,那么表示生成该版本的事务在当前事务生成 ReadView 前已经提交,所以该版本可以被当前事务访问。
  • 如果被访问版本的 事务ID >= low_limit_id 值,那么表示生成该版本的事务在当前事务生成 ReadView 后才开启,所以该版本不可以被当前事务访问。
  • 如果被访问版本的 事务ID在 up_limit_id和m_low_limit_id 之间,那就需要判断一下版本的事务ID是不是在 trx_ids 列表中,如果在,说明创建 ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问;
    如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。

举例

1、insert undo log为什么commit之后就可以删?(假如此时数据库维护的待分配的最大事务id=457)

RC下:事务A执行select,生成read view(trx_ids=null,low_limit_id=457,up_limit_id=457)。事务B 进场,执行insert并commit(由于执行了增删改操作,mysql给事务事务id=457,同时mysql自身维护全局事务id+1=458),事务A再次select,生成新的read view(此时属性发变化,trx_ids=null,low_limit_id=458,up_limit_id=458)。事务B刚才新插入的那条记录的trx_id=457。根据mvcc可见性机制,事务ID < up_limit_id(457<458),该条记录可见。这证明了两个事,一:事务A查看事务B 插入的记录时,根本没去undo  log里找数据,所以undo log可删,二:正时因为RC下每次select都重新生成read view机制,实现读已提交

RR下:事务A执行select,生成read view(trx_ids=null,low_limit_id=457,up_limit_id=457)。事务B 进场,执行insert并commit(由于执行了增删改操作,mysql给事务事务id=457,同时mysql自身维护全局事务id+1=458),事务A再次select,不会生成新的read view(此时属性还是第一次select时样子,trx_ids=null,low_limit_id=457,up_limit_id=457)。事务B刚才新插入的那条记录的trx_id=457。根据mvcc可见性机制,事务ID >= low_limit_id (457>=457),该条记录不可见。这证明了两个事,一:事务A查看事务B 插入的记录时,根本没去undo  log里找数据,所以undo log可删,二:正时因为RR下的只有第一次select才生成read view机制,实现可重复读

总结:通过上面两个例子发现,在RC,RR中,针对insert操作产生undo log,RC,RR都快照读都没用上,所以MySQL索性就直接删了。

2、update/delete undo log为什么commit之后就不可以删?(假如此时数据库维护的待分配的最大事务id=457)

RR下:事务A执行select,生成read view(trx_ids=null,low_limit_id=457,up_limit_id=457)。事务B 进场,对某条记录执行update并commit(由于执行了增删改操作,mysql给事务事务id=457,同时mysql自身维护全局事务id+1=458),事务A再次select,不会生成新的read view(属性还是老样子,trx_ids=null,low_limit_id=457,up_limit_id=457)。事务B刚才更新的那条记录的trx_id=457。根据mvcc可见性机制,事务ID >= low_limit_id (457>=457),该条记录不可见。此时情况就来了,如果这条记录不可见,事务A就会根据这条记录上的roll_ptr去undo log找对应的记录。针对update、insert操作。如果事务B  commit就删undo log,此时事务A去undo log中时找不到历史数据的,这不满足RR的可重复读条件

大白话讲解MySQL 索引,页分裂,行溢出,事务相关推荐

  1. mysql影响行数解析_详解MySQL的数据行和行溢出机制

    一.行 有哪些格式? 你可以像下面这样看一下你的mysql行格式设置. 其实mysql的数据行有两种格式,一种就是图中的 compact格式,还有一种是redundant格式. compact是一种紧 ...

  2. mysql 聚簇索引页分裂_mysql聚簇索引的页分裂原理是什么 mysql聚簇索引的页分裂原理解析...

    本篇文章小编给大家分享一下mysql聚簇索引的页分裂原理解析,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 在MySQL中,MyISAM采用的是非聚簇索引的,InnoDB存 ...

  3. MySQL索引页结构

    1. 前言 「页」是InnoDB管理存储空间的基本单位,也是内存和磁盘交互的基本单位.也就是说,哪怕你需要1字节的数据,InnoDB也会读取整个页的数据,下次读取的数据如果恰巧也在这个页里,就能命中缓 ...

  4. mysql索引如何分裂节点_从MySQL Bug#67718浅谈B+树索引的分裂优化(转)

    原文链接:http://hedengcheng.com/?p=525 问题背景 今天,看到Twitter的DBA团队发布了其最新的MySQL分支:Changes in Twitter MySQL 5. ...

  5. mysql索引如何分裂节点_Oracle索引分裂(Index Block Split)

    索引分裂:index  block split :就是索引块的分裂,当一次DML 事务操作修改了索引块上的数据,但是旧有的索引块没有足够的空间去容纳新修改的数据,那么将分裂出一个新的索引块,旧有块的部 ...

  6. MySQL索引创建、删除及事务控制

    文章目录 一.索引概述 二.索引的优点与缺点 三.创建索引的原则依据 四.索引的分类与创建 4.1 索引的分类 4.2 索引的创建 4.2.1 普通索引 4.2.2 唯一索引 4.2.3 全文索引 4 ...

  7. 用十万级数据进行讲解MySQL索引基础

    文章目录 索引简介 主键索引 唯一索引 普通索引 组合索引 全文索引 索引简介 索引是为了提高数据库查询效率而生的.对于一些查询多,修改少的字段很适合用索引,以提高查询效率.如果是修改多的话,用索引会 ...

  8. 详细讲解MySQL索引与联合索引

    背景:  为了提高数据库效率,建索引是家常便饭:那么当查询条件为2个及以上时,我们是创建多个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下. 一.联合索引 ...

  9. B 树和 B+ 树的插入、删除和数据页分裂机制

    B树和B+树 索引在磁盘中的存储 扇区 B+树比平衡二叉树.B树在磁盘中的优化 Innodb数据文件在磁盘中的储存 数据页 数据页分裂 行溢出 Innodb中的B+树如何处理重复Key的 B树和B+树 ...

最新文章

  1. VIM查找替换归纳总结
  2. java-developer 性能是怎么样的?
  3. 进程的创建与可执行程序的加载
  4. uva 11584——Partitioning by Palindromes
  5. python网络爬虫开发从入门到精通_Python突击-从入门到精通到项目实战
  6. Go语言基础(四)—String与其他基本数据类型的转换
  7. 《java编程思想》读书笔记(二)第五章(2)
  8. 杭州电信域名解析服务器,浙江电信的DNS是多少?
  9. text 热敏打印机_便携热敏打印机API参考手册.pdf
  10. 图片加密信息(16进制)
  11. 总有个短信发来一行乱码_总是收到乱码短信
  12. C++ BMP转JPG方法二
  13. Unity3D_3dsMax-Vray材质导入
  14. 小程序 - 判断元素是否在页面的显示区域内 wx.createIntersectionObserver
  15. 关系抽取调研-工业界
  16. 10019---访问远程Redis服务。Connect to Remote Redis Server
  17. ecshop 数据库字典
  18. Java中的请求域(Request)《笔记》
  19. 中国分电器及点火线圈市场现状研究分析与发展前景预测报告(2022)
  20. 视频怎么用伪原创手机 抖音短视频如何去水印

热门文章

  1. python加减乘除简单计算和打印信封格式
  2. CSS背景、文本、字体
  3. AppStore生存之道:国内iOS开发者创业经验分享
  4. 怎么将视频转为音频mp3格式?这些转换方法一分钟就能学会
  5. Unity扩展-Package Manager都有哪些插件-说明(中)
  6. 喜大普奔,电脑版微信可以刷朋友圈了!
  7. Android系统中如何添加USB网络共享
  8. html table 标签 边框 边距问题
  9. 计算机和专用软件能整体入账吗,好用的电脑记账软件有哪些?
  10. 他能一举拿下阿里的offer,靠的绝对不止运气!