使用update语句修改表中数据 updateset多条数据


使用update语句修改表中数据 updateset多条数据

文章插图
概述今天主要简单介绍一下select语句的流程、update语句执行流程以及涉及的两阶段提交协议,仅供参考 。
redo log(innodb引擎独有,循环写,空间固定会用完,比如配置一组4个文件,每个文件大小为4GB,则总共可以记录4GB的操作)是物理日志,记录的在“在某个数据页上做了什么修改”;
binlog(mysql的server层实现,日志追加写)是逻辑日志,记录的是这个语句的原始逻辑 。
如果每一次数据更新的时候都需要写进磁盘,然后磁盘找对应记录,然后再更新,整个过程IO成本、查找成本都很高,而mysql数据库采用WAL(write-ahead logging)来解决这个问题,关键在先写日志,再写磁盘 。也就是当数据库进行更新的时候,innodb引擎先把记录写到redo log,并更新内存,这时候更新就算完成了,同时innodb引擎会在适当时候更新到磁盘 。当redo log空间不够时则先将redo log内容写到磁盘再继续工作 。
先理解mysql数据库如何实现崩溃恢复?1、MySQL没有开启Binary log的情况下:
InnoDB存储引擎通过redo和undo日志可以safe crash recovery数据库,当数据crash recovery时,通过redo日志将所有已经在存储引擎内部提交的事务应用redo log恢复,所有已经prepared但是没有commit的transactions将会应用undo log做roll back 。然后客户端连接时就能看到已经提交的数据存在数据库内,未提交被回滚的数据需要重新执行 。
2、MySQL开启Binary log 的情况下:
为了保证存储引擎和MySQL数据库上层的二进制日志保持一致(因为备库通过二进制日志重放主库提交的事务,假设主库存储引擎已经提交而二进制日志没有保持一致,则会使备库数据丢失造成主备数据不一致),引入二阶段提交(two phase commit or 2pc)
理解mysql数据库select语句流程update语句执行流程换个角度考虑为什么要设计两阶段提交2PC协议也成为2段提交,1prepare阶段,2commit阶段 。
所谓的两个阶段是指:第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)
为什么要有两阶段提交?这是为了让redo log和binlog日志之间的逻辑一致 。
由于redo log和binlog是两个独立的逻辑,如果不用两阶段提交,那就是先写完redo log,再写binlog,或者采用反过来的顺序 。
以update语句为例:update t set c = c+1 where id=2;
假设执行 update 语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了 crash,会出现什么情况呢?
1、先写 redo log 后写 binlog
假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启 。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1 。
但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句 。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句 。
然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同 。
即:
在写binlog之前崩溃时:
1)重启恢复:发现没有commit,回滚
2)备份恢复:没有binlog
3)结果:事务一致
2、先写 binlog 后写 redo log
如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0 。但是 binlog 里面已经记录了“把 c 从 0 改成 1”这个日志 。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同 。


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: