mysql底层原理
⼀:MySql架构
1.⼀条sql语句如何执⾏的:mysql5.7查询缓存默认关闭,mysql8缓存已被移除。
1. 存储引擎对⽐:
MySIAM:表级锁定,不⽀持事务,已读为主
InnoDB:⽀持事务,⽀持外键,⽀持⾏级别和表级别的锁定,B+索引,效率⾼Memory:内存存储。
Archive:⽤于存储和检索⼤量很少引⽤的历史、存档、安全审计信息,不⽀持事务。
1. mysql架构
局部性原理:读取磁盘的数据,它附近的数据也会被读取到内存,操作形同⼀般4k,mysql中读取每页的数据16k,Innodb设置了⼀个内存叫Buffer Pool,默认128M,读取数据时先去buffer中读取,写数据也是先写到buffer中,为了不产⽣脏页,innodb有专门的后台线程把buffer 中的数据写到磁盘中,这个动作叫刷脏。为了防⽌数据库宕机造成数据不⼀致,Innodb会把修改操作写到Redo log(重做⽇志)中,事务的acid的持久化就是这个⽇志实现的,(为啥不直接写到磁盘,因为写磁盘的数据不是连续的,io效率低,⽇志是顺序的,快速。)redo log⼤⼩是固定的,⼀旦写满,就会触发buffer到磁盘的同步。和redo log 还有⼀个undo log 是重做⽇志,记录的修改之前的数据,⽤于回滚。
Binlog⽤于1.主从复制2数据恢复。
7.⼀条更新语句的执⾏(省略了undo log)
Redo两阶段是为了防⽌写⼊binlog失败。
⼆:MySql索引原理
1. 为何需要索引
数据是以⽂件存储在磁盘,查询的时候不能挨个查数据,有了索引直接可以到该数据所在的位置
1. InnoDB索引类型:普通索引,唯⼀索引,主键索引,聚集索引
聚集索引:索引键值的逻辑顺序和表数据⾏的物理存储顺序⼀致,主键索引就是⼀种聚集索引。
3.InnoDB索引采⽤B+树
4.聚集索引的叶⼦节点存储的数据⾏。⼆级索引(⾮聚集索引)叶⼦节点存储的是索引字段和所在⾏的主键字段,当查询⼀个name的⼆级索引时,先到⼆级索引中叶⼦节点name的主键id值,然后在主键索引中查id的叶⼦结点,叶⼦结点存储的就是数据⾏的数据。
》如果定义了主键,主键就作为聚集索引,
》如果没有定义主键索引的话,InnoDB会选择第⼀个不包含NULL的唯⼀索引作为主键索引,
》如果这个唯⼀也没有,InnoDB会选择⼀个6字节的ROWID字段作为隐藏的聚集索引,会随着记录的写⼊⽽作为主键递增。
5.联合索引:多个字段作为⼀个索引,最左匹配,
6.覆盖索引:如果select的数据在⼆级索引的节点就能到就不会再去主键索引中查。
7.回表:查询⼆级索引,再根据⼆级索引的数据到主键索引去查询数据叫回表
8.在什么字段上建⽴索引
Wher
9.什么时候索引会失效
》索引列上使⽤函数(replace substr concat sum count avg)表达式、计算等
》字符串不加引号 where name=123
》like条件中前⾯带%
》NOT LIKE 查询
》!= <> not in在某些条件下可以使⽤索引
三:MySql事务和锁机制
1. 事务四⼤特性;ACID
原⼦性:事务要么成功,要么失败
⼀致性:数据前后保持⼀致
隔离性:多个事务之间是相互隔离,互不影响的
持久性:只要事务操作成功,不会因为数据库宕机等外界因素恢复到原来的状态(redo log实现)1. 事务并发问题
脏读:事务A读到事务B还未提交的数据
不可重复读:事务A读到事务B已提交的数据,前后数据不⼀致。
幻读:事务A读取的数据是事务B插⼊了新⾏。
1. 事务隔离级别:
未提交读:没解决任何问题
已提交读:解决了脏读
可重复读:解决了脏读和不可重复读
串⾏化:三个问题都解决了
1. InnoDB堆事务隔离级别的⽀持
1. InnoDB的两⼤实现⽅法查看mysql索引
5.1 LBCC:读取数据的时候锁定数据,锁的并发控制
5.2 MVCC:修改数据的时候建⽴⼀个快照,多版本的并发控制
Mvcc实现的原理:我可以查到在我这个事务修改的数据或者我这个事务开始之前已经存在并提交的数据,在我这个事务之后新增修改的数据我是查不到的。
Innodb给每⾏记录增加三个字段:
创建版本号:插⼊或更新⾏的最后⼀个事务id
删除版本号:数据被删除或标志为旧数据的事务id
Rowed:主键id
1. 锁的分类
》共享锁:slect 。。lock in share mode
》排他锁:⼀个事务获取了⼀⾏数据的排它锁,其他事务就不能再获取这⼀⾏数据的共享锁或者排他锁,但不表⽰不能读数据,⽐如select * from a where name=‘2’ 这个select是不会加任何锁的,所以不会阻塞。Update delete 会⾃动加排它锁
》意向锁:给⼀⾏数据加上共享锁之前,数据库会⾃动给这张表加上意向共享锁,同样的,给⼀⾏数据加上排他锁之前,数据库会⾃动给这张表加上意向排他锁,这样其他事务就不⽤每⾏遍历查看数据是否有共享或者排它锁。提⾼效率。
1. ⾏锁的原理:是给索引加锁。
》如果有⼆级索引的话,会通过⼆级索引查聚集索引。锁住索引对应的记录。表如果没有索引,我们知道会创建⼀个隐藏的rowid作为聚集索引,查询的时候因为没创建索引,所以会全表查询,这样就锁住了所有的隐藏rowid索引,所以外界看来就是整张表锁住了。
1. 锁的算法。⽐如 id建⽴唯⼀索引有 1 4 7 10 数据
》记录锁:当使⽤唯⼀索引(唯⼀索引和主键索引)使⽤等值查询,精确匹配到⼀条记录的时候,使⽤的就是记录锁,⽐如 where id=1
》间隙锁:查询的记录不存在,⽆论等值查询还是范围查询,使⽤的都是间隙锁,⽐如:where id>4 an
d id <7 或者 where id=6 锁住的
(4,7] ,间隙锁是左开右闭。
》临键锁:当使⽤范围查询,不仅命中了记录,还包含了间隙锁,这使⽤的就是临键锁,相当于记录锁加上间隙锁,⽐如where id>5and
id<9 ,命中了7,临建锁锁住的是最后⼀个key的下⼀个左开右闭区间,所以锁住了(4,10]。
1. innodb各隔离级别的实现⽅式
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论