事务ID:
当一个事务开始以后,oracle会给事务分配一个XID。
事务表:
undo表空间的undo段的第一个数据块里面放了一个事务表,介于块大小的限制,最多可以放47个事务。
段头块:
Undo表空间里的undo段里的第一个块叫做undo段的段头块,这段头块里面有一个事务表,事务表最多有47行,每行放一个事务,也就是说一个undo段最多有47个活动事务。
事务开始以后会分配一个事务ID,然后在undo表空间里找一个undo段,把自己的信息写到undo段的段头块的事务表里面。
事务槽:
一个事务可能修改一个数据块(buffer),在数据块的头部有事务槽,事务槽的数量是1到255个。一个事务开始以后首先在undo段的段头块的事务表里写上自己的事务信息(一行),然后在要修改的buffer的头部的事务槽里也要写上事务信息。
回滚块:
在修改数据块的时候把修改前的数据存到回滚块里去。回滚块是实实在在存数据的,事务表和事务槽都是存事务信息的。
一个事务开始以后不管是否发生增删改都会在事务表里放上XID,并产生一个undo块。
事务ID(XID)的意义:
事务ID既是一个编号又是一个地址,XID里的信息:1.事务用了哪个回滚段(undo段)的段头块;2.使用了事务表的哪一行;3.第几次覆盖。块号(条件一)+行号(条件二)+第几次覆盖可以唯一的确定事务表中的一行。
一个事务开始以后先找到一个undo段,在段头块的事务表里写上XID,同时在undo段里找一个空闲的数据块(回滚块)用于存放修改前的数据,再把回滚块的地址(UBA,undo block address)写到事务表的槽位里(与XID同槽位)。这里就完成了undo段里的操作。
找到事务要修改的buffer,在buffer的头部的事务槽里找到一个槽位,把XID(事务ID)写上(通过XID找到事务表的对应项)。接下来事务就要修改buffer的数据了,修改时会把修改前的数据保存到undo段的数据块(undo块,回滚块)里。同时buffer的事务槽里面也有一个UBA地址,这个UBA地址指向undo段的回滚块。
事务表的UBA指向最新的undo块,而事务槽的UBA指向自己的undo块。一个事务修改使用的undo块形成链表,回滚时从最新的undo块开始向前回滚。
事务槽中的UBA指向自己的undo块这有利于事务默认隔离级别时构造cr块。
1. Undo块形成链表有利于对事务进行回滚;
2. 事务槽指向指向自己的undo块有利于构造cr块(一致性读);
3. 事务槽的XID指向事务表的对应项是为了oracle的一种提交方式(后面讲);
一个事务开始以后oracle会修改的地方:
1. 回滚段的段头块的事务表被修改;
2. 回滚块被修改;
3. 数据块(buffer)的事务槽被修改;
4. Buffer中的数据行被修改;
以上4个地方的修改都会产生redo,redo不仅仅是记录数据行的改变,事务槽的改变,undo块的改变、事务表的改变都会产生redo。