MySQL在update发现要修改值跟原值相同,会再执行修改吗?

举报
JavaEdge 发表于 2021/06/03 22:43:01 2021/06/03
【摘要】 当MySQL去更新一行,但是要修改的值跟原来的值是相同的,这时候MySQL会真的去执行一次修改吗?还是看到值相同就直接返回呢? ❌的想法一 MySQL读出数据=》发现值与原来相同=》不更新=》直接返回=》执行结束。 做一个锁实验来确认。 假设,当前表t里的值是(1,2)。 锁验证方式 sessionB的update被阻塞,加锁这个动作是InnoDB才能做的,所...

当MySQL去更新一行,但是要修改的值跟原来的值是相同的,这时候MySQL会真的去执行一次修改吗?还是看到值相同就直接返回呢?

❌的想法一

MySQL读出数据=》发现值与原来相同=》不更新=》直接返回=》执行结束。

做一个锁实验来确认。
假设,当前表t里的值是(1,2)。

  • 锁验证方式

    sessionB的update被阻塞,加锁这个动作是InnoDB才能做的,所以排除该选项

❌的想法二

MySQL调用InnoDB引擎提供的接口,但引擎发现值与原来相同,不更新,直接返回。
假设当前表里的值是(1,2)。

  • 可见性验证方式

    sessionA的第二个select语句是一致性读(快照读),它看不见session B的更新。

现在它返回(1,3),表示它看见了某个新版本,这个版本只能是session A自己的update语句做更新的时候生成。

所以答案是

✅的想法

InnoDB认真执行了“把这个值修改成(1,2)"这个操作,该加锁的加锁,该更新的更新。

你肯定觉得MySQL怎么这么笨,就不会更新前判断一下值是不是相同?不就不用浪费InnoDB多更新一次了?

其实MySQL确认过了。只是在这个语句里面,MySQL认为读出来的值,只有一个确定的 (id=1), 而要写的是(a=3),只从这两个信息是看不出来“不需要修改”的。

再看个验证例子。

  • 可见性验证方式–对照

    上面的验证结果都是在 binlog_format=statement 格式下进行的。
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.02 sec)

mysql> show variables like 'binlog_row_image';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| binlog_row_image | FULL  |
+------------------+-------+
1 row in set (0.02 sec)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

如果是binlog_format=rowbinlog_row_image=FULL,由于MySQL需要在binlog里面记录所有字段,所以在读数据时,就会把所有数据读出来。

根据上面规则,“既然读了数据,就会判断”, 因此这时,

select * from t where id=1

  
 
  • 1

结果就是 (1,2)。

同理,若是binlog_row_image=NOBLOB, 会读除blob外的所有字段,在这个例子,结果还是(1,2)。

对应代码如下,MySQL 5.6引入

  • binlog_row_image=FULL读字段逻辑

    如果binlog是row格式,并且image=full。那么read_set设为全1,表示所有的字段都要读

类似的,如果表中有timestamp字段而且设置自动更新,则更新“别的字段”的时候,MySQL会读入所有涉及的字段,这样通过判断,就会发现不需要修改。

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/115600304

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。