最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

我所理解的MySQL之一:基础架构

来源:懂视网 责编:小OO 时间:2020-11-08 22:13:33
文档

我所理解的MySQL之一:基础架构

前面所说的执行流程主要是描述查询语句,如果是更新语句还涉及到 MySQL 的日志模块。从客户端到执行器的之间的逻辑查询语句和更新语句是相同的,只是在到执行器这一层的时候,更新语句会和 MySQL 的日志模块产生交互,这是查询语句和更新语句不一样的地方。3.1 物理日志 redo log3.1.1 redo log 中记录的内容。对于 InnoDB 存储引擎来说,它有一个特有的日志模块——物理日志(重做日志)redo log,它是 InnoDB 存储引擎的日志,它所记录的是数据页的物理修改。
推荐度:
导读前面所说的执行流程主要是描述查询语句,如果是更新语句还涉及到 MySQL 的日志模块。从客户端到执行器的之间的逻辑查询语句和更新语句是相同的,只是在到执行器这一层的时候,更新语句会和 MySQL 的日志模块产生交互,这是查询语句和更新语句不一样的地方。3.1 物理日志 redo log3.1.1 redo log 中记录的内容。对于 InnoDB 存储引擎来说,它有一个特有的日志模块——物理日志(重做日志)redo log,它是 InnoDB 存储引擎的日志,它所记录的是数据页的物理修改。

3. 日志模块

前面所说的执行流程主要是描述查询语句,如果是更新语句还涉及到 MySQL 的日志模块。

从客户端到执行器的之间的逻辑查询语句和更新语句是相同的,只是在到执行器这一层的时候,更新语句会和 MySQL 的日志模块产生交互,这是查询语句和更新语句不一样的地方。

3.1 物理日志 redo log

3.1.1 redo log 中记录的内容

对于 InnoDB 存储引擎来说,它有一个特有的日志模块——物理日志(重做日志)redo log,它是 InnoDB 存储引擎的日志,它所记录的是数据页的物理修改。

举个例子,现在有一张 user 表,有一条主键 id=1,age=18 的数据,然后用户提交了下面这条 SQL,执行器准备执行。

update user set age=age+1 where id=1;复制代码

对于这条 SQL,在 redo log 中记录的内容大致是:将 user 表中主键 id=1 行的 age 字段值修改为19

3.1.2 WAL

MySQL 的更新持久化逻辑运用到了 WAL(Write-Ahead Logging,写前日志记录) 的思想:先写日志,再写磁盘。

需要注意的是这里的写日志也是写到磁盘中,但由于日志是顺序写入的,所以速度很快。而如果没有 redo log,直接更新磁盘中的数据,那么首先需要找到那条记录,然后再把新的值更新进入,由于查询和读写I/O,就相对会慢一些。

最后,当 InnoDB 引擎空闲的时候,它会去执行 redo log 中的逻辑,将数据持久化到磁盘中。

3.1.3 redo log 日志文件

redo log 日志文件大小是固定的,我把它理解为一个循环链表,链表的每个节点都可以存放日志,在这个链表中有两个指针:write(黑) 和 read(白)。

循环链表

最开始这两个指针都指向同一个节点,且节点日志元素都为空,表示此时 redo log 为空。当用户开始提交更新语句,write 节点开始往前移动,假设移动到3的位置。而此时的情况就是 redo log 中有1-3这三个日志元素需要被持久化到磁盘中,当 InnoDB 空闲时,read 指针往前移动,就代表着将 redo log 持久化到磁盘。

但这里有一种特殊情况,就是 InnoDB 一直没有空闲,write 指针一直在写入日志,直到它写到5的位置,再往前写又回到了最开始1的位置(也就是上图的位置,但不同的是链表节点中都存在日志数据)。

此时发现1的位置已经有日志数据了,同时 read 指针也在。那么这时候 write 指针就会暂停写入,InnoDB 引擎开始催动 read 指针移动,把 redo log 清空掉一部分之后再让 write 指针写入日志文件。

3.1.4 redo log 的作用

我们已经知道,redo log 中记录的是数据页的物理修改,所以 redo log 能够保证在数据库发生异常重启时,记录尚未写入磁盘,但是在重启后可以通过 redo log 来“redo”,从而不会发生记录丢失的情况,保证了事务的持久性。

这一能力也被称作 crash-safe。

3.2 归档日志 bin log

前面说到 redo log 是 InnoDB 特有的日志,而 bin log 则是属于 MySQL Server 层的日志,在默认的 Statement Level 下它记录的是更新语句的原始逻辑,即 SQL 本身。

另外需要注意的是:

  • bin log 的日志文件大小并不固定,它是“追加写入”的模式,写完一个文件后会切换到下一个文件写入。
  • bin log 没有 crash-safe 的能力。
  • bin log 是在事务最终提交前写入的,而 redo log 是在事务执行中不断写入的。
  • 3.2.1 bin log 的作用

    与 redo log 不同的是,bin log 常用于恢复数据,比如说主从复制,从节点根据父节点的 bin log 来进行数据同步,实现主从同步。

    3.3 两阶段提交

    为了让 redo log 和 bin log 的状态保持一致,MySQL 使用两阶段提交的方式来写入 redo log 日志。

    在执行器调用 InnoDB 引擎的接口将写入更新数据时,InnoDB 引擎会将本次更新记录到 redo log 中,同时将 redo log 的状态标记为 prepare,表示可以提交事务。

    随后执行器生成本次操作的 bin log 数据,并写入 bin log 的日志文件中。

    最后执行器调用 InnoDB 的提交事务接口,存储引擎把刚写入的 redo log 记录状态修改为 commit,本次更新结束。

    在这个过程中有三个步骤 add redo log and mark as prepare -> add bin log -> commit,即:

    1. 写入 redo log 日志并标记为 prepare
    2. 写入 bin log
    3. 提交事务

    如果在第二个步骤,也就是写入 bin log 之前系统崩溃或重启,启动后由于 bin log 中没有记录,会将 redo log 中的记录回滚至执行本次更新语句前。

    如果在第三个步骤前,也就是提交之前系统崩溃或重启,即便没有 commit 但是满足 redo log 中记录为 prepare 状态并且 bin log 中也有完整记录,在重启后会自动 commit,并不会回滚。

    4. 小结

    本文主要介绍 MySQL 的基础架构以及各个组成部分的功能,最后介绍了 MySQL Server 层的 bin log 和 InnoDB 特有的 redo log 这两种日志模块。

    5. 温故知新

    以下的几个问题是对本文所描述内容的提问,巩固知识,正所谓“温故而知新,可以为师矣”。

    1. 如果查询语句中字段不存在、字段有歧义、关键字拼写错误,是由哪个部分报错?
    2. 如果用户对表没有查询权限,是哪个部分报错?
    3. 为什么 MySQL 的查询缓存会无效?
    4. 一条 select 查询语句是如何执行的?
    5. MySQL 常用的存储引擎有哪些?
    6. MySQL 的日志模块有哪些?分别起到什么作用?
    7. redo log 写满了怎么办?
    8. 如何理解 redo log 的两阶段提交?
    9. redo log 和 bin log 的区别?

    更多相关免费学习推荐:mysql教程(视频)

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    我所理解的MySQL之一:基础架构

    前面所说的执行流程主要是描述查询语句,如果是更新语句还涉及到 MySQL 的日志模块。从客户端到执行器的之间的逻辑查询语句和更新语句是相同的,只是在到执行器这一层的时候,更新语句会和 MySQL 的日志模块产生交互,这是查询语句和更新语句不一样的地方。3.1 物理日志 redo log3.1.1 redo log 中记录的内容。对于 InnoDB 存储引擎来说,它有一个特有的日志模块——物理日志(重做日志)redo log,它是 InnoDB 存储引擎的日志,它所记录的是数据页的物理修改。
    推荐度:
    标签: 了解 理解 mysql
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top