1)回滚段是磁盘上的一段空间
2)当一个事务开始的时候:
首先,把变化前的数据和变化后的数据写入redo log file
其次,把变化前的数据和相关的事务信息写入回滚段
最后,才在data_buffer_cache中修改数据
3)commit做两件事:
a)写日志
b)在回滚段中标记事务为inactive(小事务还会在buffer cache里面标志)
4)undo
a)delete操作:undo为整个数据行
b)update操作:undo仅为前镜像
c)insert操作:undo为rowid
当rollback时:
delete操作,则把回滚段中的数据重新写回数据块
update操作,把前镜像修改回去
insert操作,根据记录的rowid,将此删掉
5)查询的结果集是根据时间点来判定的。
6)回滚块和数据块一样,都在sga中,也都是database_buffer_cache的一份子
7)同一个事务不能跨越回滚段,即便是其他回滚段空闲,该大事务也只能使用被分配的回滚段即使该回滚段扩展。
接下来考究单个回滚段内的使用、扩展、回缩的问题
假定一个回滚段存在extent 1,2,3,4,5
8)一个回滚段至少包含2个区
9)每个回滚段有一个回滚段头,回滚段头是一个数据块,里面记录了事务表信息。
10)回滚段的区是循环使用的:事务从extent 1的第二个块开始使用,直到extent 5的末尾
回滚段的段头的事务表也是循环使用
区的使用从一个跨越到另一个的次数,可以查询如下:
sys@ORCL> select usn,wraps from v$rollstat;
USN WRAPS
---------- ----------
0 1
11 68
12 60
13 79
14 70
15 71
16 67
17 68
11)既然回滚段是循环使用的,那为什么会扩展呢?
假定这样一种情况,存在一个事务,呆在extent 3,一直没有提交,然后回滚段循环使用到了extent 2,当extent 2使用完毕的时候发现extent 3存在未提交的事务,这时,即使extent 4,5,1中的事务都已经提交,当前事务也不能越过extent 3而去使用后面的可使用的extent,那么只好扩展新的extent,假定为extent 2-1.因为回滚段之间的区是链状串起来的,但节点2-1的下一个extent依然是extent 3,假如2-1使用完毕发现extent 3仍然存在未提交的事务,则继续扩展。回滚段在扩展后,是需要回收的。Smon进程每12h作为一个周期会对所有回滚段进行回收。shrinks表示回收的次数
sys@ORCL> select usn,optsize,shrinks from v$rollstat;
USN OPTSIZE SHRINKS
---------- ---------- ----------
0 0
1 1
2 0
3 0
4 1
5 0
6 0
7 0
8 0
9 0
10 0
12 3
12)块清除:已经提交的数据,需要标志为已经提交,从而使得后来的会话访问该数据的时候不再产生一致读而直接读该块。而如果事务提交的时候块已经被写入磁盘,则当时不会对块进行清除,需要延迟清除。当被提交但没有来得及清除的块在下次被会话读取的时候,会话会检查该块上最新的事务状态。
13)对回滚段的监控,最常用的是查看v$rollstat
字段值:
shrinks很大,可以认为回滚段设置太小