在客户端与mysql服务端建立TCP连接之后,连接器会验证用户身份,之后的所有请求全都是按照这个时候验证的身份权限进行的,所以更新用户身份证之后重新连接才会更新权限
mysql在执行过程中临时使用的内存是管理在连接对象里的,所以这个连接如果一直没断的话,占用内存就会持续上涨
缓存是以k-v的形式缓存的,所以如果执行语句有任何不同的话都是查不到缓存的
且如果表发生变化的话,建立的所有缓存都会删除
词法分析:将输入的字符序列分解成有意义的标记(关键字、标识符、操作符或常量等)
语法分析:在词法分析的基础上,检查这些标记是否遵循sql的语法规则,构建抽象语法树
会对逻辑进行重写,生成多种执行方法,评估多种执行方法,选择最优的一条
逻辑优化(查询重写):
谓词下推,尽早执行where,减少中间数据量
视图重写,将视图展开为实际的sql查询
子查询优化,子查询转换为连接join
常量折叠,提前计算可以确定的表达式
OR转UNION,便于使用索引
物理优化(决定如何执行sql):
是否使用索引以及使用什么索引
表的连接顺序
连接算法
是否使用索引排序,是否需要额外排序
调用存储引擎,真正执行查询,返回结果
在更新的时候,需要把新的值写到磁盘上,但是每次io操作会造成性能下降
所以当需要更新的时候,innoDB会把要更新的值写到redolog中,然后只更新内存
定期将redolog中的内容写到磁盘中
redolog在内存中是一组环形数组,有两个标志位——write pos和check pos
如果更新的话就写在内存,同时记录到redolog并把write pos后移
如果更新到磁盘,把redolog中的内容写到磁盘上,然后check pos后移
这样即使数据库崩溃了,但是redolog还在,仍然可以根据redolog来恢复之前操作的数据
作用:
保证事务的持久性:事务一提交就把redolog的内容写到磁盘上,保证事务的持久性
提高性能:减少IO操作,支持多线程并发写入
崩溃恢复:
记录的内容:
是物理日志,记录的是对数据做的改动
对数据页的具体修改:数据页编号、修改前后的值、修改类型(插入、更新、删除)
是server层的逻辑日志,记录的是逻辑语句
主要作用是:主从复制,同时也有数据恢复和审计追踪的作用
记录的内容:
数据恢复:将数据恢复到指定日期之前最近的一次全量备份,然后执行全量备份之后的binlog,直到指定日期即可
无论是先写redolog还是再写binlog,如果要恢复数据,两个日志不一致的话都会造成数据不一致,主要是为了保障分布式数据库的数据一致性
所以两阶段提交:
写完redolog之后redolog为prepare状态,写binlog,redolog为commit状态
事务是在存储引擎层实现的
当多个事务同时执行的话就可能造成数据不一致的问题:
脏读、丢失修改、不可重复读、幻读
为了解决多个事务对共享数据的操作安全性,提出不同的事务隔离级别:
读未提交,读已提交,可重复读,事务串行化
mysql中的事务并发控制方式实际上只有两种:锁和MVCC
锁:读写锁,可以实现读读并行,但是不能读写、写写并存
根据粒度可以分为表级锁和行级锁
MVCC:多版本并发控制方法,将一份数据存储多个版本,事务只能看到一份数据自己应该看到的版本
MVCC的实现方式依赖:隐藏字段、read view、undo log
隐藏字段:
在innoDB中,每一行数据都包含几个隐藏字段:
DB_ROW_ID: 行id,插入新行单调递增
DB_TRX_ID: 事务id,记录最后一次插入或更新该行的事务id,每次对数据进行修改时,都生成一个新的版本,将这个字段更新为当前事务的id
DB_ROLL_PTR:指向undo log的指针
read view:
是一个快照,记录了系统中所有活跃事务的id列表(已经启动但是尚未提交的事务),通过比较DB_ROW_ID和read view,可以决定这个版本的数据是否可见
DB_ROW_ID DB_ROW_ID在read view的活跃事务id列表中,说明这个版本是未提交的事务创建的,不可见 innoDB的MVCC和read view机制是行级可见性控制,每个数据行的可见性是独立判断的 对于某一行的话不可能出现后面的事务提交了前面的事务还没 undo log: 当一个事务对数据进行修改时,innoDB不仅会修改数据,还会在undo log中记录如何撤销这些更改 通过undo log可以回滚事务 在MVCC时,当有其他事务需要访问旧版本数据时,可以通过undo log找到数据历史版本 undo log分为两种: insert undo log:专门记录插入操作的undo信息,事务提交之后可以直接删除 update undo log:记录更新或删除操作的undo信息,一直保留到没有事务需要相关旧数据 如果事务很长的话,就会导致会保留很多undo log不能删除,就会占用大量内存空间 读:读的是数据快照 写:innoDB在写数据的时候会对记录加锁,在获得行的写锁之后才能进行修改,事务提交或者回滚之后才能会把这个行的写锁释放,其他事务才能继续修改这个行 所以MVCC主要用于“一致性非锁定读”,提升读操作的并发性能,对于写的话由于要获得写锁,所以都需要等其他事务提交之后才能进行写,所以都是基于最新版本的数据 那其他事务在读这一行的时候首先会通过这一行的隐藏字段和read view来判断可见性: 1.如果小于当前活跃的最小事务id,可见 2.如果不在活跃列表,则以提交,可见 3.否则的话就根据隐藏字段找到undolog,读之前的版本