暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

这种update语句,原来是这么玩的

B哥数据搬运工 2021-04-16
385

        曾经碰到有开发人员问到,如果一个update语句,更新列的当前值与旧值一致时,数据库是不是直接跳过更新操作,不会重复去做更新替换旧值的操作?        

        先插播个广告,近期我们正在招DBA,如果您现在知道怎么去印证这个update的问题,而且您准备跳槽的话,请您把简历发我,直接找我们Boss谈薪吧

        言归正传,带着这个问题,我将以下实验逐步解开疑问

        案例的实验环境数据库版本11.2.0.1(在内网11.2.0.4和19.6版也同步测过)。测试开启两个会话,Session 1是oramon用户,Session 2是sys用户:

1)在Session 1窗口,创建b2c_users表,插入1行记录,并提交。


2)在Session 2窗口,手工触发检查点,并切换新日志,目的是方便后面分析。


3)在Session 2窗口,查看日志信息,当前日志序号332,有两个成员。


4)在Session 1窗口,查到user_id=1000的user_name为Harion,接着发出update语句,把user_name更新为原先的值Harion,并提交。


5)在Session 2窗口,进行日志切换,并dump下日志序号为332的logfile。


6)在Session 1窗口,查看user_id=1000的记录,落在4号数据文件,块号为4565。表的对象ID为79434。同时,我们将user_name为Harion,dump成16进制,值为0x486172696f6e。


7)接着,我们分析dump下来的日志,通过object_id为79343,在日志里面搜索。找到对应的redo record,它包含了4个改变矢量(change vectors)。其中CHANGE #1,对应的OP是11.19(Array Update ?),可以看到下面红框中第二列,即col 1,实际存储字符长度为6,对应的变更后的值是0x486172696f6e,即为Harion。

CHANGE #2,对应的OP是5.2,即get undo header,从uba可以看到对应undo block address的地址信息。

CHANGE #3,对应的OP是5.4,即rollback or commit操作。



8)CHANGE #4,对应的OP是5.1,即update undo block操作。其中xid对应事务ID,objn对应对象ID,而最下方红框col 1,是update的前镜像,值为0x486172696f6e,即为Harion。


小结:从上面的例子,我们可以看到,就是update列的旧值与当前值是一致的,但数据库还是会去更新原先的值,同时也会生成undo信息。我们从redo的日志可以很清楚看到这个update的处理过程。


这个案例告一个段落,但从这个案例可以引申出另一个问题,如果表里面有索引,且索引字段又是更新列,当前值与旧值不一致时,会有什么不一样?索引的处理逻辑又是什么?下一篇文章将揭晓这个问题。还是那句广告,想到这问题的答案时,您如果准备跳槽的,简历转下我,您直接跟我们Boss聊哈











文章转载自B哥数据搬运工,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论