一条SQL更新语句是怎么执行的?

  • 一条SQL更新语句是怎么执行的?
    • 与查询相同部分,客户端通过连接器与MySQL建立连接,接着与表相关的查询缓存会失效,分析器语法分析,优化器选择是否走索引,与查询不同,更新操作还涉及日志模块的操作
    • 之后执行器拿到引擎给的行数据,数据更新至内存,同时写入redo log【prepare阶段】,执行器生成该操作的binlog,并将binlog写入磁盘,执行器调用提交事务接口,将刚刚写入的redo log改成commit 提交状态,更新完成【commit阶段】
    • Mysql中的WAL(write-ahead-logging 写前日志) 特点是先写日志再写磁盘
      • 两个重要的日志 redo log(物理日志)和binlog(逻辑日志)
        • redo log【InnoDB特有,是引擎层日志】
          • 具体是当有一条记录需要更新的时候,InnoDB引擎会先到redo log,并更新内存,此时更新就算缓存,之后InnoDB引擎会在系统空闲的时候,将日志记录写入磁盘
          • InnoDB的redo log 可以设置为一组4个,一个1G,一组相当于拼接成环,环中有标识擦除位置及当前写入位置,redo log 满了之后,会进行相应的擦除,而擦除之前会将记录更新到数据文件?
          • relo log 可以保证数据库异常重启之后,提交记录不丢失,这称之为 crash safe
        • bin log (归档日志)【MySQL的server层实现,所有引擎都可以使用】
      • 为什么会有两份日志?
        • 一开始没有InnoDB,MySQL存储引擎用的MyISAM,而MyISAM只有binLog的归档功能,没有crash safe 的能力,后来引入InnoDB引擎以redo log实现crash safe
        • 区别
          • 一个是引擎层,一个是server层,一个是特有,一个是所有引擎都可以使用
          • redo log是物理日志,记录的是“在某个数据页上做了什么修改”
          • binLog是逻辑日志,记录的是原始的SQL语句
          • redo log是循环写,binLog是追加写,一个文件写完可以再写另一个,不会覆盖
      • 两阶段提交(prepare阶段和commit阶段)
        • 先写redo log 再写binlog,如果redo log写完,binlog没写 ,此时数据库异常重启,那么当需要使用binlog恢复临时库时,少一条记录,与原库数据有差异
        • 先写binlog后写redo log,如果binlog写完,redo log没写,使用binlog恢复数据时,便会多出一条记录,与原库数据有差异
        • 总结:不使用两阶段提交,便会出现原库与使用binlog恢复的新库数据不一致
        • 注:redo log 和binlog都可以用于表示事务的提交状态,而两阶段提交是保持两个状态逻辑上的一致性
        • tip:常见的主备方案(可以提高读能力)是通过全量备份和binlog实现
      • redo log 用于保证crash-safe的能力,保证MySQL异常重启之后数据不丢失,binlog用于记录完整的逻辑记录,备份恢复时以binlog为基础,通过其记录的完整逻辑操作,备份出一个与原库数据一样的数据
      • 问题:一周一备还是一天一备 (系统指标 RTO 恢复目标时间)
        • 天备,恢复时间短,恢复时只需执行最近一天的修改操作
        • 周备,恢复时间长,需执行最近一周的修改操作
          • 具体选择看业务,对于较敏感的系统(不能接收恢复时间久的,也可以选择一小时备),但是频繁全量备份,很消耗存储

你可能感兴趣的:(MySQL45讲,mysql)