SQL是如何执行的?
MySQL分为两部分:Server层和储存引擎两个部分
Server层包括:连接器、查询缓存、分析器、优化器、执行器
分析器:词法分析、语法分析 词法分析将SQL语句给拆分开,识别出里面的字符串分别是什么,代表什么; 语法分析是判断这个SQL语句是不是合法
优化器:决定使用哪个索引
执行器:首先会判断一下有没有权限,然后去使用表定义的引擎的接口
日志系统
redo log(重做日志) 和 binlog(归档日志)
WAL(Write-AHead Logging):先写日志、在写磁盘
redo log(是InnoDB引擎特有的)物理日志 记录在某个数据页做什么操作
write pos:记录当前的位置
checkpoint:当前要进行擦除的部分
binlog (是server层的)逻辑日志 记录的是原始语句
binlog是追加写,redo log是循环写
两阶段提交(这个是针对redo log的):写入redolog之后处于prepare阶段,写入binlog之后,提交事务,处于commit状态
两阶段提供是为了保证两份日志之间逻辑的一致性
事务
原子性、隔离性、一致性、持久性
隔离级别:读未提交、读提交、可重复读、可串行化
启动方式:如果set autocommit=0,这个命令会将线程的自动提交给关闭掉,执行select之后就开启了事务,但是需要自己commit才可以提交;设置为set autocommit=1之后就需要显式的来提交事务
索引
索引是了提高数据的查询效率,就像书的目录一样
常见的索引模型:哈希表、有序数组、N叉树
InnoDB的索引模型
使用了B+树索引模型
索引分类:聚簇索引和非聚簇索引; 主键索引和非主键索引
覆盖索引:可以减少索引的回表次数
最左前缀原则:索引项是按照索引定义里面出现的字段顺序排序的
索引下推:在联合索引中,在索引的遍历过程中,会对索引中包含的字段优先做一个判断,直接过滤掉不满足条件的记录,减少回表的次数。
锁
全局锁:做全库的逻辑备份
(Flush tables with read lock)FTWRL 让整个数据库处于只读状态
表级锁:表锁、元数据锁(meta data lock MDL)
表锁:lock tables … read/write (不仅会限制其他线程,自己也会受到限制,如果是read,则自己也不能够write)
元数据锁:不需要显式使用的,在访问表的时候会自动加上
对一个表做增删改查的时候加读锁,对一个表做结构变更的时候,加MDL写锁。
给一个小表加字段也是可能会挂的。因为需要申请写锁,这时候可能还有线程持有读锁,后面来的线程申请读锁也是会被阻塞的
行锁
两阶段锁:在InnoDB事务中,行锁是在需要的时候才加上的,但是在事务结束之后才会释放。因此如果事务中需要锁多个行,把容易造成冲突的锁往后放。
可能会出现死锁的情况:进入等待,直到超时释放;进行死锁检测,发现死锁之后,主动进行回滚