MYSQL学习笔记--SQL更新语句的执行

MYSQL更新语句是这样子的:

mysql> update T set c=c+1 where ID=2;

更新语句跟查询语句走的流程是一样的:
在这里插入图片描述
跟查询一样,连接器----》查询缓存—》分析器----》优化器—》执行器。
与查询不同的地方,多了两个日志模块redolog和binlog.
redo log
由于每次操作如果每次对数据库的操作都写入磁盘进行持久化的,整个操作的IO成本,查找成本都很高。所以MYSQL设计者就用了WAL技术(Write-Ahead Logging).原理就是先写日志,在不忙的时候在写磁盘,提高效率。
INNODDB先把记录写入日志,更新内存,然后直接返回。redo log的大小是固定的,比如可以配置一组4个,每个1GB,总共用4G的缓存空间。同时redo log采用了循环缓冲区的数据结构,如下图:
在这里插入图片描述
当write_pos 等于check point的时候,表示缓冲区已经满了,需要先清理一下缓冲区。
有了这个设计,就可以保证crach-safe,当数据库异常重启的时候,之前提交的事物记录都不会丢失。
binlog
binlog(归档日志),是MYSQL SERVER层,不具备crach-safe能力。redo log是innodb拥有的。
不同的地方:
1 redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
2 redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
3 redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

更新语句执行流程:
1 执行器找引擎拿到ID=2这一行,如果在内存,直接从内存里面取。如果不在内存,则从磁盘里面拿。
2 拿到数据后进行+1操作,调用引擎接口写入。
3 引擎写入内存,同时写入redo log,并把状态改为prepare,告知执行器执行完成,可以随时进行提交事物
4 执行器生成binlog,并持久化到磁盘
5 执行器开始提交事务,引擎把redo log的状态从perpare改为commited
两阶段提交
其实就算让两个不同的文件保存逻辑上的一致
顺序不能变,假设:
1 先写 redo log 后写 binlog。
redo log 写完,但是没有写binlog,发生了崩溃。redo log已经写完,binlog没有写。使用binlog备份的时候就会少记录,那么用这个binlog去恢复的时候就会造成丢失数据。
2 先写 binlog 后写 redo log
binlog写完,redolog没有写入就崩溃了。那么这个事物是无效的,因为redolog没有这一条记录,但是binlog却有这条记录,从binlog恢复的时候就会多出一条事物,造成了数据的不一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值