MySQL——开篇

在跨年的这两天中,通过某课的体验课在学习MySQL实战内容,在大专的时候学习了MsSql,但是都是直接从sql语句上手,没有讲到过一些原理内容,但是学习技术不应该止步于此,应该更加深入去了解它。今天就写下这篇文章记录总结一下这两天看到内容吧。

MySQL语句的执行

先以一条简单的查询语句开始select * from T where ID=10;

对数据库进行操作前,都需要连接上数据库才能够进行语句的操作,然后数据库会一顿操作,将数据封装成结果集返回。那么里面是如何运作的呢?我在网上找到了一张图,如下:

MySQL逻辑架构图
MySQL逻辑架构图

根据这张图可以看到,整个SQL的执行过程是先通过连接器进行连接并校验权限,然后将SQL交给MySQL执行,MySQL会先查询缓存,如果命中缓存,直接将缓存数据返回,若是没有则通过分词器进行词法分析和语法分析对sql进行解析,通过优化器进行优化,最后通过执行器操作存储引擎进行数据的读写。

从整体上看,流程是这样的,非常清晰也简单易懂,但是实际上在执行的时候还有一些细节需要我们去了解。假设是一条更新语句呢,它是怎么执行的?

1
update T set c=c+1 where ID=2;

如果是在大量的更新执行的时候呢?每一条都写一次磁盘,资源消耗是不是特别大?redo log先将操作记录下来,当系统比较空闲时,或者redo log记录满了,就将这些数据一股脑全写到磁盘中。

假如我们像查询那样执行,那么在执行更新的时候,MySQL突然发生了异常,没有一些手段,这次的操作就丢失了。因此,MySQL中有redo logbinlogredo log是InnoDB特有的,用以实现cresh-safe能力,当执行更新时,先查询出这行数据,然后给这个数据进行更新,将这次的更新写入到redo log中处于prepare状态,之后交给执行器执行操作。这时候执行器又会先将操作生成binlog写入日志,再调用引擎将数据提交,并修改刚刚所写的redo log的状态改为commit,至此更新操作完成。

这样在出现异常之后,可以从redo log再将这个prepare语句恢复。当我们误删数据时,可以将数据全量恢复到最近的一次备份,并将这个时间段的binlog重放一遍恢复到误删的那个时刻。这种两段提交日志的方式主要为了保证redo logbinlog的逻辑一致,避免写好了redo log而没写好binlog造成数据丢失。下面给出某课中的反证来理解为什么会使用这样的两段提交。

反证
反证