mysql

查询语句执行过程:

连接器:

在客户端与mysql服务端建立TCP连接之后,连接器会验证用户身份,之后的所有请求全都是按照这个时候验证的身份权限进行的,所以更新用户身份证之后重新连接才会更新权限

mysql在执行过程中临时使用的内存是管理在连接对象里的,所以这个连接如果一直没断的话,占用内存就会持续上涨

查询缓存:

缓存是以k-v的形式缓存的,所以如果执行语句有任何不同的话都是查不到缓存的

且如果表发生变化的话,建立的所有缓存都会删除

分析器:

词法分析:将输入的字符序列分解成有意义的标记(关键字、标识符、操作符或常量等)

语法分析:在词法分析的基础上,检查这些标记是否遵循sql的语法规则,构建抽象语法树

优化器:

会对逻辑进行重写,生成多种执行方法,评估多种执行方法,选择最优的一条

逻辑优化(查询重写):

        谓词下推,尽早执行where,减少中间数据量

        视图重写,将视图展开为实际的sql查询

        子查询优化,子查询转换为连接join

        常量折叠,提前计算可以确定的表达式

        OR转UNION,便于使用索引

物理优化(决定如何执行sql):

        是否使用索引以及使用什么索引

        表的连接顺序

        连接算法

        是否使用索引排序,是否需要额外排序

执行器:

调用存储引擎,真正执行查询,返回结果

三大日志:

redolog:

在更新的时候,需要把新的值写到磁盘上,但是每次io操作会造成性能下降

所以当需要更新的时候,innoDB会把要更新的值写到redolog中,然后只更新内存

定期将redolog中的内容写到磁盘中

redolog在内存中是一组环形数组,有两个标志位——write pos和check pos

如果更新的话就写在内存,同时记录到redolog并把write pos后移

如果更新到磁盘,把redolog中的内容写到磁盘上,然后check pos后移

这样即使数据库崩溃了,但是redolog还在,仍然可以根据redolog来恢复之前操作的数据

作用:

保证事务的持久性:事务一提交就把redolog的内容写到磁盘上,保证事务的持久性

提高性能:减少IO操作,支持多线程并发写入

崩溃恢复:

记录的内容:

是物理日志,记录的是对数据做的改动

对数据页的具体修改:数据页编号、修改前后的值、修改类型(插入、更新、删除)

binlog:

是server层的逻辑日志,记录的是逻辑语句

主要作用是:主从复制,同时也有数据恢复和审计追踪的作用

记录的内容:

  • STATEMENT:记录的是 SQL 语句本身。优点是日志量较小,但某些情况下可能导致主从数据不一致(如依赖于当前时间戳或随机数的查询)。
  • ROW:记录的是每一行的具体变化(增删改)。这种方式更加精确,能够确保主从数据的一致性,但产生的日志量较大。
  • MIXED:默认模式,结合了 STATEMENT 和 ROW 的优点。在存在数据不一致的时候自动切换为 ROW 格式以保证数据一致性。

数据恢复:将数据恢复到指定日期之前最近的一次全量备份,然后执行全量备份之后的binlog,直到指定日期即可

redolog + binlog ——两阶段提交:

无论是先写redolog还是再写binlog,如果要恢复数据,两个日志不一致的话都会造成数据不一致,主要是为了保障分布式数据库的数据一致性

所以两阶段提交:

写完redolog之后redolog为prepare状态,写binlog,redolog为commit状态

mysql事务:

事务是在存储引擎层实现的

当多个事务同时执行的话就可能造成数据不一致的问题:

脏读、丢失修改、不可重复读、幻读

为了解决多个事务对共享数据的操作安全性,提出不同的事务隔离级别:

读未提交,读已提交,可重复读,事务串行化

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<read view中最小活跃事务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,读之前的版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值