一条SQL更新语句的执行过程?

更新一个简单的sql语句:

mysql> update user set age='23' where id='1';

在上一章中的查询流程,更新流程基本会走一遍。区别在于:

  • 分析器区别出这是一条更新的语句;优化器使用当前的id做索引,然后执行负责执行。
  • 更新流程还涉及两个重要的日志模块:redo log(重做日志)和binlog(归档日志)。

redo log --InnoDB持有的日志

MySQL每一次更新操作都需要写进磁盘,磁盘也要找到对应的记录,再更新,整个过程IO成本,查找成本都很高。
MySQL采用WAL(Write-Ahead Logging)技术,先写日志,再写磁盘来提高该效率。

  • 当有一条记录更新时,InnoDB就会先把记录写到redo log,在更新内存。然后适当的时候(系统比较空闲),将记录更新到磁盘
  • InnoDB的redo log的大小需要根据实际业务量进行设置。
//查看redo log的大小
mysql> show variables like 'innodb_log%'; 

+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 16777216 |
| innodb_log_checksums        | ON       |
| innodb_log_compressed_pages | ON       |
| innodb_log_file_size        | 50331648 |
| innodb_log_files_in_group   | 2        |
| innodb_log_group_home_dir   | ./       |
| innodb_log_write_ahead_size | 8192     |

//设置后重启数据库生效
  • 有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe

binlog --Server层的日志

  • 两者的区别

    redo log binlog
    InnoDB持有 Server层持有
    物理日志,某个数据页做了什么修改 逻辑日志,语句的原始逻辑
    空间固定后会用完 可以追加写入,不会覆盖以前的日志
  • 再看执行器和InnoDB在执行上面update语句时的内部过程,浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的。
    在这里插入图片描述

两阶段提交

  • 目的是为了让两份日志之间的逻辑一致。

举例说明:怎样让数据库恢复到半个月内任意一秒的状态?如某天下午2点发现中午十二点有一次勿删表,需要找回数据。怎么做呢?

  1. 找最近一次的全量备份,运气好的话,找到前天晚上的一个备份,从这个恢复到临时库
  2. 从备份点的时间开始,将备份的binlog依次取出,重放到中午误删操作前的那刻
  • 为什么需要两阶段提交
  • 先写redo log后写binlog。还没写完binlog时,MySQL异常了重启,恢复后,本例中age应该=23;但是由于binlog没有写完crash了,binlog没有记录这个语句;若用binlog来恢复临时库,恢复出来age=21,与原库中的值不同。
  • 先写binlog再写redo log,binlog写后,crash了,redo log还没写,恢复后,这个事务无效,age=21。但binlog恢复后,记录了将age=23,会多出一个事务,与原库值也不同。
  • 除了误删库需要用这样的过程来恢复数据。需要扩容,多搭建备库来增加系统的读能力时,现在常用做法也是全量备份加上应用binlog来实现,这样也会导致线上出现主从不一致
  • redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。

在什么场景下,一天一备会比一周一备更有优势呢?

  • 一天一备份的话,只要找到这天的全备,加入这天某段时间的binlog来恢复,如果一周一备份,假设是周一,而你要恢复的数据是周日某个时间点,那就,需要全备+周一到周日某个时间点的全部binlog用来恢复,时间相比前者需要增加很多;看业务能忍受的程度
  • 一周一备份的话,需要确保整个一周的binlog都完好无损,否则将无法恢复;而一天一备,只要保证这天的binlog都完好无损;

本文是通过学习极客时间“MySQL实战45讲”,做的学习笔记,有错误的地方,请网友提出,大家共同学习,后续陆续更新!扫描下方二维码,可以共同学习。

在这里插入图片描述

发布了5 篇原创文章 · 获赞 0 · 访问量 54

猜你喜欢

转载自blog.csdn.net/qq_34220643/article/details/104889053