1、基础架构:一条SQL查询语句是如何执行的?
1.1 连接器
连接器负责跟客户端建立连接、获取权限、维持和管理连接。
mysql -h$ip -P$port -u$user -p
输完命令之后,输入密码。
1.2 查询缓存
MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。
1.3 分析器
分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是什么,代表什么。
MySQL 从你输入的”select”这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名 T”,把字符串“ID”识别成“列 ID”。
做完了这些识别以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。
1.4 执行器
执行语句。
2、日志系统:一条SQL更新语句是如何执行的?
2.1 redo long (重做日志)
在一个办公室里,有一个写字板(白板)和一个记事本(正式账本),用于记录每一天的待办事项和完成情况。具体过程如下:
场景
-
记录新任务:
- 当有新的任务需要记录时,秘书会先写在白板上,同时在内存中留有一份副本,以便随时查询当前的任务进度。
- 这样秘书可以迅速记录下来,不影响办公效率。
-
任务完成更新:
- 当某个任务完成时,秘书会在白板上修改状态,并在内存中同步更新这个任务的状态。
- 如果当前有新的任务需要记录,同样在白板上添加记录。
-
账户最终核算:
- 到了当天工作结束(或者系统闲暇时),秘书会把白板上的记录同步更新到记事本上(正式账本)。
- 这样,即使第二天忘记了新任务和完成状态,也可以通过查看记事本获取前一天的全部信息。
图示
白板记录和账本更新的过程
白板(临时记录) 记事本(最终记录)
初始状态: 初始状态:
白板为空 记事本为空
记录新任务: 未同步
TASK 1: Pending 记事本为空
更新任务状态: 未同步
TASK 1: Completed 记事本为空
记录新任务: 未同步
TASK 2: Pending 记事本为空
同步白板到记事本:
白板状态:
TASK 1: Completed
TASK 2: Pending 记事本状态:
TASK 1: Completed
TASK 2: Pending
白板和账本协作保证数据安全
任务来了,并记录在白板上 -> 办公室突然断电重启 -> 恢复后,秘书通过白板和账本找到任务数据,并继续工作
实现细节
白板相当于 InnoDB 中的 redo log,而记事本相当于是数据库的数据文件。通过这样的设计,即便系统突然崩溃,重启后依然可以通过 redo log 恢复到最新的状态。
关键点
- Write-Ahead Logging (WAL):所有的更新操作先写到 redo log,然后才写到数据文件。
- Crash-Safe 能力:即使数据库发生了异常重启,只要 redo log 中有记录,已经提交的事务也不会丢失。
2.2 binlog
前面我们讲过,MySQL 整体来看,其实就有两块:一块是 Server 层,它主要做的是 MySQL 功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。上面我们聊到的粉板 redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。
为什么会有两份日志?因为MySQL 自带的引擎 MyISAM不能 crash-safe 。binlog 日志只能用于归档。
而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统——也就是 redo log 来实现 crash-safe 能力。
未完待续。。。。。