无法无天过路客
Java程序员一枚,喜欢记录收集技术文章
展开
-
MySQL - 揭秘MySQL性能优化:执行计划深度解析!
比如说x1=xx,在索引里只要做等值比较,扫描数据比较少,那么可能就会挑x1的索引,做一个索引树的查找,在执行计划里,其实就是一个ref的方式,找到几条数据之后,接着做一个回表,回到聚簇索引里去查出每条数据的完整数据,接着加载到内存里,根据每条数据的x2字段的值做筛选。此时,假设t1表的数据量是10万条,而物化表的数据量只有500条,那么此时完全可以改成全表扫描物化表,对每个数据值都到t1表里根据x1这个字段的索引进行查找,查找物化表的这个值是否在t1表的x1索引树里,如果在的话,那么就符合条件了。原创 2024-04-12 07:50:51 · 45 阅读 · 0 评论 -
MySQL - 深入MySQL索引的秘密(二)
另外,覆盖索引其实不是一种索引,他就是一种基于索引查询的方式罢了,他的意思就是针对类似select xx1,xx2,xx3 from table order by xx1,xx2,xx3这样的语句,在这种情况下,你仅仅需要联合索引里的几个字段的值,那么其实就只要扫描联合索引的索引树就可以了,不需要回表去聚簇索引里找其他字段了,所以这个时候,需要的字段值直接在索引树里就能提取出来,不需要回表到聚簇索引,这种查询方式就是覆盖索引。这个时候也会用到索引的。原创 2024-04-12 07:50:32 · 30 阅读 · 0 评论 -
MySQL - 深入MySQL索引的秘密(一)
所以此时就会出现一个过程,叫做页分裂,就是万一你的主键值都是你自己设置的,那么在增加一个新的数据页的时候,实际上会把前一个数据页里主键值较大的,挪动到新的数据页里来,然后把你新插入的主键值较小的数据挪动到上一个数据页里去,保证新数据页里的主键值一定都比上一个数据页里的主键值大。如果依然还是查找不到呢?所以既然如此,你直接就可以定位到id=3的数据一定是在数据页2里的,假设你有很多的数据页,在主键目录里就会有很多的数据页和最小主键值,此时你完全可以根据二分查找的方式来找你要找的id到底在哪个数据页里。原创 2024-04-11 07:35:51 · 43 阅读 · 0 评论 -
MySQL - 掌握MySQL锁的必备知识
在MySQL里,假设有一行数据摆在那儿不动,此时有一个事务来了要更新这行数据,这个时候他会先琢磨一下,看看这行数据此时有没有人加锁,一看没人加锁,说明他是第一个人,此时这个事务就会创建一个锁,里面包含了自己的trx_id和等待状态,然后把锁跟这行数据关联在一起。如果你查询的时候加独占锁,那么跟其他更新数据的事务加的独占锁都是互斥的,如果你查询的时候加共享锁,那么跟其他查询加的共享锁是不互斥的,但是跟其他事务更新数据就加的独占锁是互斥的,跟其他查询加的独占锁也是互斥的。默认情况下需要加锁吗?原创 2024-04-11 07:35:37 · 35 阅读 · 0 评论 -
MySQL - Read Committed隔离级别是如何基于ReadView机制实现的?
这个时候事务A发起查询,发现当前这条数据的trx_id是70,也就是说数据ReadView的事务id范围之间,说明是他生成ReadView之前就有个活跃的事务,是这个事务修改了这条数据的值,但是此时这个事务B还没提交,所以ReadView的m_ids活跃事务列表里,是有[60,70]两个id的,所以此时根据ReadView的机制,此时事务A是无法查询到事务B修改的值B的。一个非常核心的要点在于,当你一个事务设置他处于RC隔离级别的时候,他是每次发起查询都重新生成一个ReadView。原创 2024-04-10 07:35:03 · 37 阅读 · 0 评论 -
MySQL - MySQL的RR隔离级别是如何基于ReadView机制实现的?
接着此时事务A再次查询,此时会发现符合条件的有2条数据,一条是原始值的那个数据,一条是事务C插入的那条,但是事务C插入的那条数据的trx_id是80,这个80是大于自己ReadView的max_trx_id的,说明是自己发起查询之后,这个事务才启动的,所以此时这条数据是不能查询的。他的意思就是在事务A开启查询的时候,事务B当时是在运行的。RR级别下,这个事务读取一条数据,无论读多少次,都是一个值,别的事务修改数据之后,哪怕提交了,你也是看不到人家修改的值的,这就避免了不可重复读的问题。原创 2024-04-10 07:35:31 · 42 阅读 · 0 评论 -
MySQL - 基于undo log多版本链条实现的ReadView机制到底是什么?
这个时候事务A再次查询,此时查询的时候,会发现一个问题,那就是此时数据行里的trx_id=59,那么这个trx_id是大于ReadView里的min_trx_id(45),同时小于ReadView里面的max_trx_id(60)的,说明更新这条数据的事务,很可能就跟自己差不多同时开启的,于是会看一下这个trx_id=59,是否在ReadView的m_ids列表里。此时事务A来查询这条数据的值,会发现这个trx_id=45,居然跟自己的ReadView里的creator_trx_id是一样的,说明什么?原创 2024-04-09 08:23:10 · 697 阅读 · 0 评论 -
MySQL - MySQL数据库的事务(二)
我们在上图中可以看到,数据行里的值变成了值C,trx_id是事务C的id,也就是69,然后roll_pointer指向了本次修改之前生成的undo log,也就是记录了事务B修改的那个值,包括事务B的id,同时事务B修改的那个undo log还串联了最早事务A插入的那个undo log,如图所示,过程很清晰明了。总之,事务之间互相都完全不影响。默认就是DEFAULT值,这个就是MySQL默认支持什么隔离级别就是什么隔离级别,MySQL默认是RR级别,自然你开发的业务系统的事务也都是RR级别的了。原创 2024-04-09 08:22:57 · 29 阅读 · 0 评论 -
MySQL - MySQL数据库的事务(一)
但是如果你希望的是事务A开始执行的时候,第一次查询读到的是值A,然后后续你希望事务执行期间,读到的一直都是这个值A,不管其他事务如何更新这个值,哪怕他们都提交了,你就希望读到的一直是第一次查询到的值A,那么你就是希望可重复读的。但是要说有问题,也可以是有问题的,就是事务A可能第一次查询到的是A值,那么他可能希望的是在事务执行期间,如果多次查询数据,都是同样的一个A值,他希望这个A值是他重复读取的时候一直可以读取到的,他希望这行数据的值是可重复读的。原创 2024-04-08 08:34:27 · 30 阅读 · 0 评论 -
MySQL - Redo日志和Undo日志介绍
在我们执行增删改操作的时候,首先会在Buffer Pool中更新缓存页,在更新完Buffer Pool中的缓存页之后,必须要写一条redo log,这样才能记录下来我们对数据库做的修改。redo log可以保证我们事务提交之后,如果事务中的增删改SQL语句更新的缓存页还没刷到磁盘上去,此时MySQL宕机了,那么MySQL重启过后,就可以把redo log重做一遍,恢复出来事务当时更新的缓存页,然后再把缓存页刷到磁盘就可以了。redo log本质是保证事务提交之后,修改的数据绝对不会丢失的。原创 2024-04-08 08:32:38 · 31 阅读 · 0 评论 -
MySQL - Buffer Pool介绍(二)
这个时候没有空闲的缓存页,如果要加载新的数据,就要把LRU链表队尾的缓存页刷入磁盘,而不是无人访问的那个缓存页。基于LRU算法淘汰缓存页,从磁盘加载一个数据页到缓存页的时候,这个缓存页的描述数据块会被放到LRU链表的头部,所以所有有数据的缓存页都会在LRU链表中,最近被加载的缓存页,会被放到LRU链表的头部。另外一边,后台线程不停的把LRU链表的冷数据区域的缓存页及flush链表的缓存页刷入到磁盘,来清空缓存页,然后flush链表和LRU链表中的缓存页不停的在减少,free链表中的缓存页在不停的增加。原创 2024-04-08 08:32:25 · 24 阅读 · 0 评论 -
MySQL - Buffer Pool介绍(一)
所以数据库为Buffer Pool设计一个free链表,它是一个双向链表数据结构,这个free链表里,每个节点就是一个空闲的缓存页的描述数据块的地址,也就是说,只要有一个缓存页是空闲的,那么他的描述数据块就会被放入这个free链表中。只不过这个时候,Buffer Pool中的一个一个的缓存页都是空的,里面什么都没有,要等数据库运行起来后,当我们要对数据执行增删改操作的时候,才会把数据对应的页从磁盘文件里读取出来,放入Buffer Pool中的缓存页中。但是如何数据页已经被缓存了,那么就会直接使用了。原创 2024-04-08 08:32:07 · 26 阅读 · 0 评论 -
MySQL - BinLog介绍
最后在redo日志中写入commit标记的意义是用来保持redo log日志与binlog日志一致的。假设我们在提交事务的时候,一共有上图5、6、7三个步骤,必须是三个步骤都执行完毕,才算是提交了事务。那么在我们刚完成步骤5的时候,也就是redo log刚刚刷入磁盘文件的时候,mysql宕机了,此时怎么办?这个时候因为没有最终的事务commit标记在redo日志里,所以此次事务可以判定为不成功。原创 2024-04-08 08:31:54 · 25 阅读 · 0 评论 -
MySQL - InnoDB存储引擎
这样一条SQL语句是如何执行的呢?首先肯定的是我们的系统通过一个数据库连接发送到MySQL上,然后肯定会经过SQL接口、解析器、优化器、执行器几个环节,解析SQL语句,生成执行计划,接着去由执行器负责这个计划的执行;调用InnoDB存储引擎的接口去执行。原创 2024-04-08 08:31:41 · 233 阅读 · 0 评论 -
MySQL - MySQL架构设计
上面就是一个最简单的SQL语句的两种实现路径,要完成这个SQL语句的目标,两个路径都可以做到,但是哪一种更好呢?这个SQL语句,我们用人脑是直接就可以处理一下,只要懂SQL语法的人,立刻就知道它是什么意思,但是MySQL自己本身也是一个系统,是一个数据库管理系统,他没办法直接理解这些SQL语句。MySQL内部首先提供了一个组件,就是SQL接口(SQL Interface),他是一套执行SQL语句的接口,专门用于执行我们发送给MySQL的那些增删盖茶的SQL语句。所以此时有一个关键的组件,就是查询解析器。原创 2024-04-08 08:31:26 · 231 阅读 · 0 评论