【MySQL实战45讲笔记】02、一条SQL更新语句是如何执行的?

大家好,我是被白菜拱的猪。

一个热爱学习废寝忘食头悬梁锥刺股,痴迷于girl的潇洒从容淡然coding handsome boy。

  1. WAL、crash-safe、redo log、binlog

  2. binlog 为什么没有 crash-safe:

    binlog 没有能力恢复“数据页”。

  3. redo log 与 binlog 的区别

  4. 一条SQL更新语句执行过程:

    • 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
    • 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
    • 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
    • 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
    • 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
  5. 两阶段提交:

    • 先提交 redo log,发生crash,之后临时库恢复丢失
    • 先提交 binlog,恢复出来就多一条数据
    • 数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。
  6. 怎么恢复到任一时刻

    首先找到最近的全量备份,然后提取 binlog,然后恢复到发生错误的那一时刻。

  7. 能不能没有 binlog

    一个是归档。redo log 是循环写,写到末尾是要回到开头继续写的。这样历史日志没法保留,redo log 也就起不到归档的作用。

    binlog 作为 MySQL 一开始就有的功能,被用在了很多地方。其中,MySQL 系统高可用的基础,就是 binlog 复制

此讲是《MySQL实战45讲》第二讲的阅读笔记。上一篇讲的是一条 SQL 查询语句是如何执行的,可以大致了解 MySQL 的基础架构,而更新语句与查询语句前面大致相同,最关键的不同的是更新涉及到了 MySQL 的日志系统

什么是 WAL、redo log、binlog、crash-safe、两阶段提交?为什么要两阶段提交?redo log 与 binlog的区别?为什么 binlog 没有 crash-safe能力…相信大家在阅读的时候与我一般都有此疑惑,也希望通过我的语言加上对文章内容的理解能够将其讲清楚、讲明白。

redo log

在 MySQL 中,假如我们每次更新都要对磁盘进行 I/O 操作,首先要寻道要找到那条记录,然后在进行修改,其代价是很大的,所以有了 redo log(重做日志)的出现,也就是我们先把操作记录在 redo log 中,更新内存,让存储引擎在空闲的时候在将 redo log 记录的操作写到磁盘中。

看到这里时,心中有一个疑问,**那写日志不也是写在磁盘上,为什么这样性能就提高了呢?**通过查找了解到,写日志是顺序写,而执行更新操作时是随机写,要先查写到哪里才进行写操作。举个简单的例子,在笔记本写笔记时我们是一行一行写的快还是先找到这个字要写到第几页在写快,答案是显而易见的。

以上操作先写日志在写磁盘就是 WAL 技术,其全称为 Write-Ahead Logging

crash-safe

除了能够提高性能,redo log 还有一个重要的能力就是 crash-safe。crash-safe就是当数据库发生异常重启时,之前提交的数据都不会丢失,如突然停电。

那么redo log是如何保证 crash-safe 的呢?

InnoDB 中 redo log 是固定大小的(redo log 是 InnoDB 引擎特有的)它采用的是循环写,可以想象成一个圈,有两个指针 write pos,check point 来记录位置。write pos 是记录当前位置,一边写一边往后移,check point 记录的是要擦出的位置,也是循环写往后移,因为是固定大小,所以要擦出流出空间写入,擦出的意思就是说将数据更新到磁盘中。

假如此时数据库异常重启,没有更新到磁盘中的数据保存还保存在 redo log 中,并没有丢失。而 binlog 并没有这种能力,为什么没有这种能力,还需先要了解什么是 binlog?

binlog

binlog 是归档日志,主要用在备份,假如DBA说可以让数据库恢复到半个月内任意一秒的状态,也就意味着它存有半个月的 binlog,同时系统会定期做整库备份。与 redo log 不同的是 binlog 采用的追加写的形式,不像 redo log 产生擦除覆盖。redo log采用的循环写,而且是 InnoDB 特有的。

猜你喜欢

转载自blog.csdn.net/weixin_44226263/article/details/113869413