- 一条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层实现,所有引擎都可以使用】
- redo log【InnoDB特有,是引擎层日志】
- 为什么会有两份日志?
- 一开始没有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 恢复目标时间)
- 天备,恢复时间短,恢复时只需执行最近一天的修改操作
- 周备,恢复时间长,需执行最近一周的修改操作
- 具体选择看业务,对于较敏感的系统(不能接收恢复时间久的,也可以选择一小时备),但是频繁全量备份,很消耗存储
- 两个重要的日志 redo log(物理日志)和binlog(逻辑日志)
一条SQL更新语句是怎么执行的?
最新推荐文章于 2022-09-01 17:04:01 发布