今天突然在想,ORACLE是怎么进行UNDO的?

时间:2022-09-27 15:49:11
SQL> create table test(id int);


SQL> insert into test values(1);



SQL> insert into test values(2);



SQL> commit;

SQL> select * from test;

        ID
----------
         1
         2

SQL> update test set id=3;



SQL> select * from test;

        ID
----------
         3
         3

SQL> rollback;


SQL> select * from test;

        ID
----------
         1
         2

SQL> 

请问下有没有人知道当ROLLBACK的时候ORACLE是如何进行回滚的?
直接把BEFORE IMAGE从UNDO BLOCK中复制回DATA BLOCK里?
还是说用一个相反的SQL语句,就上例来说
update test set id=1 where rowid=...
update test set id=2 where rowid=...

31 个解决方案

#1


应该是 相反语句 一般通过日志恢复的

我试过修改大数据后rollback 发现速度跟修改的速度差不多

#2


这个话题可就大喽

undo的东西是非常多的,不同的语句会产生不同的undo,连select语句都会产生undo操作

#3


undo是进行dml语句是用来进行rollback和保证一致性读的作用,

所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。

#4


引用 3 楼 inthirties 的回复:
undo是进行dml语句是用来进行rollback和保证一致性读的作用,

所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。
呵呵  首先谢谢你的回答
可我怎么看不太懂你的回答 还是你没理解我想问什么

#5


引用 2 楼 majy 的回复:
这个话题可就大喽

undo的东西是非常多的,不同的语句会产生不同的undo,连select语句都会产生undo操作
单纯的select会产生UNDO吗?

#6


undo只对dml语句有效,未进行commit和已经commit的数据,存放的地方是不同的,未commit的数据,保存在数据库的回滚段(10g中升为回滚表空间)中,处于回滚段中的数据,只有同一连接的用户能看到修改结果(包括增、删、改),commit后的数据保存在表所在的表空间中,所有有查看被修改表权限的用户都会看到修改结果,未commit的数据修改可以进行回退,回退时只是简单的将回滚段中的数据丢弃,commit过的数据修改将不能回退,但管理员用户可以通过日志挖掘找到执行dml那条数据的执行时间点(日戳)(条件是记录有该操作及该操作以后的日志还在,要保存所有数据库的操作日志,数据库须运行在归档模式下,否则当检测点进程切换检测点时,日志文件组中的文件将重复被使用,文件组中最旧的文件将被新的日志覆盖),在oracle10g中,还可以通过“闪回”看到旧数据。

#7


引用 6 楼 new_bird_0001 的回复:
未commit的数据修改可以进行回退,回退时只是简单的将回滚段中的数据丢弃¡­

两个问题
1,你看清我的问题了吗
2,你这段话从什么地方看来的

#8


引用 4 楼 wh62592855 的回复:
引用 3 楼 inthirties 的回复:
 undo是进行dml语句是用来进行rollback和保证一致性读的作用,

 所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。
呵呵  首先谢谢你的回答
 可我怎么看不太懂你的回答 还是你没理解我想问什么


这里告诉你两个方面

1.  ml语句会产生undo记录 单纯的查询语句和ddl语句是不会产生undo记录的

2.  undo保存的是dml语句对应的操作前的旧的映像和新的映像。

至于如果回滚的机理不是很好解释了,涉及到的细小知识点太多了,简而言之就是根据undo里只有提交了的数据才能被写入到数据块里,undo是一个和表segement分开的空间。

#9


我也很想学习,希望高手多给些指导,谢谢.

#10


引用 8 楼 inthirties 的回复:
引用 4 楼 wh62592855 的回复:
引用 3 楼 inthirties 的回复:
undo是进行dml语句是用来进行rollback和保证一致性读的作用,

所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。
呵呵  首先谢谢你的回答
可我怎么看不太懂你的回答 还是你没理解我想问什么


这里告诉你两个方面

1.  ml语句会产生undo记录 单纯的查询语句和ddl语句是不会产生undo记录的

2.  undo保存的是dml语句对应的操作前的旧的映像和新的映像。

至于如果回滚的机理不是很好解释了,涉及到的细小知识点太多了,简而言之就是根据undo里只有提交了的数据才能被写入到数据块里,undo是一个和表segement分开的空间。

呵呵 我比较好奇的就是回滚机理的小细节
不知道是把旧的映像复制回去覆盖新的映像,还是自动生成一个相反的DML语句进行恢复。

另外我对你的回答中有一点还有点不太明白,请解答一下好吗?
那就是UNDO里保存新的映像吗?
我记得好像UNDO里只保存BEFORE IMAGE,AFTER IMAGE只是在DATA BUFFER里保存,并在一定条件下发生CHECKPOINT时被写入DATA FILE中。

#11


如果需要ROLLBACK的时候就去UNDO SEGMENT中取出相应的BEFORE IMAGE进行回滚

#12


引用 5 楼 wh62592855 的回复:
引用 2 楼 majy 的回复:
 这个话题可就大喽

 undo的东西是非常多的,不同的语句会产生不同的undo,连select语句都会产生undo操作
单纯的select会产生UNDO吗?


我不清楚你们指的单纯的select语句包不包括只读查询,只读查询会产生undo的,目的是为了一致性读,另外,只读性查询为了数据块的清出(clean out)也会产生undo

#13


把它理解為緩存,能容易理解些.

#14


回滚的机理,简而言之就是通过itl槽里记录的undo块的地址找到undo块,取出undo记录中的对于的旧的映像,从而用以前的旧值,放入数据块中,对数据库已经做过的修改进行了回滚。这里确实不需要把修改后的映像记录。


理解为緩存,也不行。
和缓存概念是不一样的,缓存是提高access速度,而这里是作为history的列表记录

只读查询会产生undo的,目的是为了一致性读
这里也是不对的,dml能产生undo,undo其中一个目的就是保证dirty data的一致性读。对于一致性读,机理和rollback类似,也是通过itl里的记录来进行操作的。

#15


关注

#16


举个实际的例了

9iSQL> create table t (aa char(2000), bb char(2000), cc char(2000));

Table created.

9iSQL> insert into t select '1', '2', '3' from all_objects where rownum <= 500;

500 rows created.

9iSQL> commit;

Commit complete.

9iSQL> set autotrace traceonly
9iSQL> select * from t;

500 rows selected.

Statistics
----------------------------------------------------------
          1  recursive calls
          1  db block gets
        622  consistent gets
          0  physical reads
       4920  redo size
      13042  bytes sent via SQL*Net to client
        866  bytes received via SQL*Net from client
         35  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        500  rows processed


看到了吗?只是个查询,产和了4920的 redo size,这些内容都是为了undo做准备的

#17


jf

#18


引用 14 楼 inthirties 的回复:
回滚的机理,简而言之就是通过itl槽里记录的undo块的地址找到undo块,取出undo记录中的对于的旧的映像,从而用以前的旧值,放入数据块中,对数据库已经做过的修改进行了回滚。这里确实不需要把修改后的映像记录。


理解为緩存,也不行。
和缓存概念是不一样的,缓存是提高access速度,而这里是作为history的列表记录

只读查询会产生undo的,目的是为了一致性读
这里也是不对的,dml能产生undo,undo其中一个目的就是保证dirty data的一致性读。对于一致性读,机理和rollback类似,也是通过itl里的记录来进行操作的。

这么说来,你认为ORACLE是把UNDO中修改前的映像复制回去覆盖被修改了的DATA BLOCK?

另外我同意你的观点,不能简单的理解为缓存,根本不是一个概念。呵呵 学习不能图省事

#19


引用 16 楼 majy 的回复:
举个实际的例了

9iSQL> create table t (aa char(2000), bb char(2000), cc char(2000));

Table created.

9iSQL> insert into t select '1', '2', '3' from all_objects where rownum <= 500;

500 rows created.

9iSQL> commit;

Commit complete.

9iSQL> set autotrace traceonly
9iSQL> select * from t;

500 rows selected.

Statistics
----------------------------------------------------------
          1  recursive calls
          1  db block gets
        622  consistent gets
          0  physical reads
      4920  redo size
      13042  bytes sent via SQL*Net to client
        866  bytes received via SQL*Net from client
        35  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        500  rows processed


看到了吗?只是个查询,产和了4920的 redo size,这些内容都是为了undo做准备的

从你的实验来看好像是这样哦。。UNDO产生REDO

#20


再加30分。 呵呵 喜欢这种讨论的气氛

#21


引用 19 楼 wh62592855 的回复:
引用 16 楼 majy 的回复:
 举个实际的例了

 9iSQL> create table t (aa char(2000), bb char(2000), cc char(2000));

 Table created.

 9iSQL> insert into t select '1', '2', '3' from all_objects where rownum  <= 500;

 500 rows created.

 9iSQL> commit;

 Commit complete.

 9iSQL> set autotrace traceonly
 9iSQL> select * from t;

 500 rows selected.

 Statistics
 ----------------------------------------------------------
           1  recursive calls
           1  db block gets
         622  consistent gets
           0  physical reads
       4920  redo size
       13042  bytes sent via SQL*Net to client
         866  bytes received via SQL*Net from client
         35  SQL*Net roundtrips to/from client
           0  sorts (memory)
           0  sorts (disk)
         500  rows processed


 看到了吗?只是个查询,产和了4920的 redo size,这些内容都是为了undo做准备的

 从你的实验来看好像是这样哦。。UNDO产生REDO


这里要注意,这里的redo,并不是undo造成的,

这里的redo是由于延迟块清除所造成的,

可以搜索一下有关的信息。

#22


只读查询?刚去搜了一下没搜到相关内容
平时用的SELECT不就是只读查询吗?

#23


我刚在网上看到篇文档automatic undo internals
好像评论说挺好的
正在看
看完了讨论

有兴趣的话留个邮箱我发给你

#24


The undo entry for a row is the previous value of the column and the operation necessary to undo the action. The 
opposite of an update is an update using to previous value.
 The example below is an undo entry for a single column 
update. Note that the entire row is not copied, just the old column values and sufficient information to undo the 
action. 
*----------------------------- 
* Rec #0x3  slt: 0x00  objn: 22101(0x00005655)  objd: 22101  tblspc: 6(0x00000006) 
*       Layer:  11 (Row)   opc: 1   rci 0x02    
Undo type:  Regular undo   Last buffer split:  No  
Temp Object:  No  
Tablespace Undo:  No  
rdba: 0x00000000 
*----------------------------- 
KDO undo record: 
KTB Redo  
op: 0x02  ver: 0x01   
op: C  uba: 0x02000004.0005.02 
KDO Op code: URP  xtype: XA  bdba: 0x01c00007  hdba: 0x01c00006 
itli: 1  ispac: 0  maxfr: 4863 
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 0 
ncol: 8 nnew: 1 size: 0 
col  5: [ 3]  c2 1d 33 


这是文章中的一段话,我觉得那段红色的字说明了是用相反的一个操作去还原。

#25


roll back要做什么事情
When we ROLLBACK:
• We undo all of the changes made. This is accomplished by reading the data back
from the ROLLBACK (undo) segment, and in effect, reversing our operation. If we
inserted a row, a ROLLBACK will delete it. If we updated a row, a rollback will
reverse the update. If we deleted a row, a rollback will re‐insert it again.
•All locks held by our session are released, and everyone who was enqueued
waiting on locks we held will be released.
从上可以看出,rollback首先导致 
1.回滚数据,把我们的操作回退,(读写undo block)
2.释放当前会话的锁.

#26


关于select 为什么会产生延迟块清楚.
可以查看这一篇文章,http://blog.csdn.net/knowhow/archive/2008/01/13/2042266.aspx
搜索这一段

在第6章中,我们曾经讨论过数据锁以及如何管理它们。我介绍了数据锁实际上是数据的属性,存储在块首部。这就带来一个副作用,下一次访问这个块时,可能必须“清理”这个块,换句话说,要将这些事务信息删除。这个动作会生成redo,并导致变脏(原本并不脏,因为数据本身没有修改),这说明一个简单的SELECT有可能生成redo,而且可能导致完成下一个检查点时将大量的块写至磁盘。不过,在大多数正常的情况下,这是不会发生的。如果系统中主要是小型或中型事务(OLTP),或者数据仓库会执行直接路径加载或使用DBMS_STATS在加载操作后分析表,你会发现块通常已经得到“清理”。如果还记得前面“COMMIT做什么?”一节中介绍的内容,应该知道,COMMIT时处理的步骤之一是:如果块还在SGA中,就要再次访问这些块,如果可以访问(没有别人在修改这些块),则对这些块完成清理。这个 活动称为提交清除(commit cleanout),即清除已修改块上事务信息。最理想的是,COMMIT可以完成块清除,这样后面的SELECT(读)就不必再清理了。只有块的UPDATE才会真正清除残余的事务信息,由于UPDATE已经在生成redo,所用注意不到这个清除工作。

#27


什么是延迟块清除:
提交事务处理时,不清除此锁定信息,而是在下一个查询读取块时清除.这称为延迟的块清除.

#28


rollback要做逆向操作的.

#29


谢谢大家的回答
那看来答案就是执行逆操作了

#30


关注

#31


学习

#1


应该是 相反语句 一般通过日志恢复的

我试过修改大数据后rollback 发现速度跟修改的速度差不多

#2


这个话题可就大喽

undo的东西是非常多的,不同的语句会产生不同的undo,连select语句都会产生undo操作

#3


undo是进行dml语句是用来进行rollback和保证一致性读的作用,

所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。

#4


引用 3 楼 inthirties 的回复:
undo是进行dml语句是用来进行rollback和保证一致性读的作用,

所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。
呵呵  首先谢谢你的回答
可我怎么看不太懂你的回答 还是你没理解我想问什么

#5


引用 2 楼 majy 的回复:
这个话题可就大喽

undo的东西是非常多的,不同的语句会产生不同的undo,连select语句都会产生undo操作
单纯的select会产生UNDO吗?

#6


undo只对dml语句有效,未进行commit和已经commit的数据,存放的地方是不同的,未commit的数据,保存在数据库的回滚段(10g中升为回滚表空间)中,处于回滚段中的数据,只有同一连接的用户能看到修改结果(包括增、删、改),commit后的数据保存在表所在的表空间中,所有有查看被修改表权限的用户都会看到修改结果,未commit的数据修改可以进行回退,回退时只是简单的将回滚段中的数据丢弃,commit过的数据修改将不能回退,但管理员用户可以通过日志挖掘找到执行dml那条数据的执行时间点(日戳)(条件是记录有该操作及该操作以后的日志还在,要保存所有数据库的操作日志,数据库须运行在归档模式下,否则当检测点进程切换检测点时,日志文件组中的文件将重复被使用,文件组中最旧的文件将被新的日志覆盖),在oracle10g中,还可以通过“闪回”看到旧数据。

#7


引用 6 楼 new_bird_0001 的回复:
未commit的数据修改可以进行回退,回退时只是简单的将回滚段中的数据丢弃¡­

两个问题
1,你看清我的问题了吗
2,你这段话从什么地方看来的

#8


引用 4 楼 wh62592855 的回复:
引用 3 楼 inthirties 的回复:
 undo是进行dml语句是用来进行rollback和保证一致性读的作用,

 所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。
呵呵  首先谢谢你的回答
 可我怎么看不太懂你的回答 还是你没理解我想问什么


这里告诉你两个方面

1.  ml语句会产生undo记录 单纯的查询语句和ddl语句是不会产生undo记录的

2.  undo保存的是dml语句对应的操作前的旧的映像和新的映像。

至于如果回滚的机理不是很好解释了,涉及到的细小知识点太多了,简而言之就是根据undo里只有提交了的数据才能被写入到数据块里,undo是一个和表segement分开的空间。

#9


我也很想学习,希望高手多给些指导,谢谢.

#10


引用 8 楼 inthirties 的回复:
引用 4 楼 wh62592855 的回复:
引用 3 楼 inthirties 的回复:
undo是进行dml语句是用来进行rollback和保证一致性读的作用,

所以dml语句会产生undo记录。undo的记录和redo log不一样,undo保存的是dml语句对应的操作前的旧的映像和新的映像。单纯的查询语句和ddl语句是不会产生undo记录的,不过查询语句会用到undo记录来保证一致性读。
呵呵  首先谢谢你的回答
可我怎么看不太懂你的回答 还是你没理解我想问什么


这里告诉你两个方面

1.  ml语句会产生undo记录 单纯的查询语句和ddl语句是不会产生undo记录的

2.  undo保存的是dml语句对应的操作前的旧的映像和新的映像。

至于如果回滚的机理不是很好解释了,涉及到的细小知识点太多了,简而言之就是根据undo里只有提交了的数据才能被写入到数据块里,undo是一个和表segement分开的空间。

呵呵 我比较好奇的就是回滚机理的小细节
不知道是把旧的映像复制回去覆盖新的映像,还是自动生成一个相反的DML语句进行恢复。

另外我对你的回答中有一点还有点不太明白,请解答一下好吗?
那就是UNDO里保存新的映像吗?
我记得好像UNDO里只保存BEFORE IMAGE,AFTER IMAGE只是在DATA BUFFER里保存,并在一定条件下发生CHECKPOINT时被写入DATA FILE中。

#11


如果需要ROLLBACK的时候就去UNDO SEGMENT中取出相应的BEFORE IMAGE进行回滚

#12


引用 5 楼 wh62592855 的回复:
引用 2 楼 majy 的回复:
 这个话题可就大喽

 undo的东西是非常多的,不同的语句会产生不同的undo,连select语句都会产生undo操作
单纯的select会产生UNDO吗?


我不清楚你们指的单纯的select语句包不包括只读查询,只读查询会产生undo的,目的是为了一致性读,另外,只读性查询为了数据块的清出(clean out)也会产生undo

#13


把它理解為緩存,能容易理解些.

#14


回滚的机理,简而言之就是通过itl槽里记录的undo块的地址找到undo块,取出undo记录中的对于的旧的映像,从而用以前的旧值,放入数据块中,对数据库已经做过的修改进行了回滚。这里确实不需要把修改后的映像记录。


理解为緩存,也不行。
和缓存概念是不一样的,缓存是提高access速度,而这里是作为history的列表记录

只读查询会产生undo的,目的是为了一致性读
这里也是不对的,dml能产生undo,undo其中一个目的就是保证dirty data的一致性读。对于一致性读,机理和rollback类似,也是通过itl里的记录来进行操作的。

#15


关注

#16


举个实际的例了

9iSQL> create table t (aa char(2000), bb char(2000), cc char(2000));

Table created.

9iSQL> insert into t select '1', '2', '3' from all_objects where rownum <= 500;

500 rows created.

9iSQL> commit;

Commit complete.

9iSQL> set autotrace traceonly
9iSQL> select * from t;

500 rows selected.

Statistics
----------------------------------------------------------
          1  recursive calls
          1  db block gets
        622  consistent gets
          0  physical reads
       4920  redo size
      13042  bytes sent via SQL*Net to client
        866  bytes received via SQL*Net from client
         35  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        500  rows processed


看到了吗?只是个查询,产和了4920的 redo size,这些内容都是为了undo做准备的

#17


jf

#18


引用 14 楼 inthirties 的回复:
回滚的机理,简而言之就是通过itl槽里记录的undo块的地址找到undo块,取出undo记录中的对于的旧的映像,从而用以前的旧值,放入数据块中,对数据库已经做过的修改进行了回滚。这里确实不需要把修改后的映像记录。


理解为緩存,也不行。
和缓存概念是不一样的,缓存是提高access速度,而这里是作为history的列表记录

只读查询会产生undo的,目的是为了一致性读
这里也是不对的,dml能产生undo,undo其中一个目的就是保证dirty data的一致性读。对于一致性读,机理和rollback类似,也是通过itl里的记录来进行操作的。

这么说来,你认为ORACLE是把UNDO中修改前的映像复制回去覆盖被修改了的DATA BLOCK?

另外我同意你的观点,不能简单的理解为缓存,根本不是一个概念。呵呵 学习不能图省事

#19


引用 16 楼 majy 的回复:
举个实际的例了

9iSQL> create table t (aa char(2000), bb char(2000), cc char(2000));

Table created.

9iSQL> insert into t select '1', '2', '3' from all_objects where rownum <= 500;

500 rows created.

9iSQL> commit;

Commit complete.

9iSQL> set autotrace traceonly
9iSQL> select * from t;

500 rows selected.

Statistics
----------------------------------------------------------
          1  recursive calls
          1  db block gets
        622  consistent gets
          0  physical reads
      4920  redo size
      13042  bytes sent via SQL*Net to client
        866  bytes received via SQL*Net from client
        35  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        500  rows processed


看到了吗?只是个查询,产和了4920的 redo size,这些内容都是为了undo做准备的

从你的实验来看好像是这样哦。。UNDO产生REDO

#20


再加30分。 呵呵 喜欢这种讨论的气氛

#21


引用 19 楼 wh62592855 的回复:
引用 16 楼 majy 的回复:
 举个实际的例了

 9iSQL> create table t (aa char(2000), bb char(2000), cc char(2000));

 Table created.

 9iSQL> insert into t select '1', '2', '3' from all_objects where rownum  <= 500;

 500 rows created.

 9iSQL> commit;

 Commit complete.

 9iSQL> set autotrace traceonly
 9iSQL> select * from t;

 500 rows selected.

 Statistics
 ----------------------------------------------------------
           1  recursive calls
           1  db block gets
         622  consistent gets
           0  physical reads
       4920  redo size
       13042  bytes sent via SQL*Net to client
         866  bytes received via SQL*Net from client
         35  SQL*Net roundtrips to/from client
           0  sorts (memory)
           0  sorts (disk)
         500  rows processed


 看到了吗?只是个查询,产和了4920的 redo size,这些内容都是为了undo做准备的

 从你的实验来看好像是这样哦。。UNDO产生REDO


这里要注意,这里的redo,并不是undo造成的,

这里的redo是由于延迟块清除所造成的,

可以搜索一下有关的信息。

#22


只读查询?刚去搜了一下没搜到相关内容
平时用的SELECT不就是只读查询吗?

#23


我刚在网上看到篇文档automatic undo internals
好像评论说挺好的
正在看
看完了讨论

有兴趣的话留个邮箱我发给你

#24


The undo entry for a row is the previous value of the column and the operation necessary to undo the action. The 
opposite of an update is an update using to previous value.
 The example below is an undo entry for a single column 
update. Note that the entire row is not copied, just the old column values and sufficient information to undo the 
action. 
*----------------------------- 
* Rec #0x3  slt: 0x00  objn: 22101(0x00005655)  objd: 22101  tblspc: 6(0x00000006) 
*       Layer:  11 (Row)   opc: 1   rci 0x02    
Undo type:  Regular undo   Last buffer split:  No  
Temp Object:  No  
Tablespace Undo:  No  
rdba: 0x00000000 
*----------------------------- 
KDO undo record: 
KTB Redo  
op: 0x02  ver: 0x01   
op: C  uba: 0x02000004.0005.02 
KDO Op code: URP  xtype: XA  bdba: 0x01c00007  hdba: 0x01c00006 
itli: 1  ispac: 0  maxfr: 4863 
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 0 
ncol: 8 nnew: 1 size: 0 
col  5: [ 3]  c2 1d 33 


这是文章中的一段话,我觉得那段红色的字说明了是用相反的一个操作去还原。

#25


roll back要做什么事情
When we ROLLBACK:
• We undo all of the changes made. This is accomplished by reading the data back
from the ROLLBACK (undo) segment, and in effect, reversing our operation. If we
inserted a row, a ROLLBACK will delete it. If we updated a row, a rollback will
reverse the update. If we deleted a row, a rollback will re‐insert it again.
•All locks held by our session are released, and everyone who was enqueued
waiting on locks we held will be released.
从上可以看出,rollback首先导致 
1.回滚数据,把我们的操作回退,(读写undo block)
2.释放当前会话的锁.

#26


关于select 为什么会产生延迟块清楚.
可以查看这一篇文章,http://blog.csdn.net/knowhow/archive/2008/01/13/2042266.aspx
搜索这一段

在第6章中,我们曾经讨论过数据锁以及如何管理它们。我介绍了数据锁实际上是数据的属性,存储在块首部。这就带来一个副作用,下一次访问这个块时,可能必须“清理”这个块,换句话说,要将这些事务信息删除。这个动作会生成redo,并导致变脏(原本并不脏,因为数据本身没有修改),这说明一个简单的SELECT有可能生成redo,而且可能导致完成下一个检查点时将大量的块写至磁盘。不过,在大多数正常的情况下,这是不会发生的。如果系统中主要是小型或中型事务(OLTP),或者数据仓库会执行直接路径加载或使用DBMS_STATS在加载操作后分析表,你会发现块通常已经得到“清理”。如果还记得前面“COMMIT做什么?”一节中介绍的内容,应该知道,COMMIT时处理的步骤之一是:如果块还在SGA中,就要再次访问这些块,如果可以访问(没有别人在修改这些块),则对这些块完成清理。这个 活动称为提交清除(commit cleanout),即清除已修改块上事务信息。最理想的是,COMMIT可以完成块清除,这样后面的SELECT(读)就不必再清理了。只有块的UPDATE才会真正清除残余的事务信息,由于UPDATE已经在生成redo,所用注意不到这个清除工作。

#27


什么是延迟块清除:
提交事务处理时,不清除此锁定信息,而是在下一个查询读取块时清除.这称为延迟的块清除.

#28


rollback要做逆向操作的.

#29


谢谢大家的回答
那看来答案就是执行逆操作了

#30


关注

#31


学习