redo和undo
1.1 oracle 9i 任务执行过程
--DML 更新数据操作:
1.创建一个改变向量(保存改变之前的数据)描述undo数据块的改变;
2.创建改变向量(保存改变之后的数据),描述数据块的改变;
3.合并两个改变向量为日志记录,写入日志缓冲区
4.创建undo记录插入undo表空间;
5. 改变数据块的数据;
所以任务报告为:
--任务报告
1.
创建undo块(数据文件2)的改变向量(方法为记录undo记录的内容)
2.
创建table数据块的改变向量
3a
合并两个改变向量,创建改变记录
3b
将改变记录复制到日志缓冲区
4
应用undo块改变向量(undo记录的redo change vector,创建undo记录)
5
应用table块改变向量
1.2 oracle 9i日志缓冲区瓶颈
所有会话进程向同一个日志缓冲区复制改变向量。
引入redo allocation latch:
用户进程尝试请求redo latch来在日志缓冲区保留部分空间;
存在问题:大量进程争用redo allocation latch,
消耗CPU资源,’自旋’ CPU的进程循环争用redo latch;
概况为一个进程的每一次变更,一条记录,一次log buffer
内存分配
1.3 oracle 10g 引入 private redo buffer
和IMU
--priate redo log buffer
Oracle 10g引入的。
每个进程有私有的日志缓冲区,一个事务中每次变更都写入这个进程的私有的日志缓冲区中;让事务提交后,这个进程获取一此公共的log buffer即可。
私用用redo allocation latch
保护,公共的用redo copy latch保护;
--IMU:In-Memory-Undo
Oracle 10g引入。
每个进程的私有日志缓冲区的一部分。进程将undo
重做日志写入IMU;
IMU 采用IMU latch来保护。最后IMU的记录和priavate redo log buffer日志记录合并。写入公共的redo
log buffer;
1.4 oracle10g任务处理顺序
--DML 更新数据操作:
1. 创建一个改变向量描述undo数据块的改变;
2. 创建改变向量,描述数据块的改变;
3 undo改变向量存入IMU日志缓冲区
Table改变向量存储private log buffer
6. 将IMU
记录和Pirvate log buffer记录合并成一条改变记录,结束事务
7.讲重做改变记录复制到日志缓冲区,并改变这个块。
--IMU
IMU池有lacth保护,池个数=transation/10
当124KB空间使用满了,回退到oracle9i的机制
--oracle数据块的存储信息
Tab 0 row 4 @0x1d3f
//表示第一个块,记录5,实际的存储地址为@0x1d3f
Col 0:[2] c1 0a
//第一列,为两个字符的空间,内容为c10a;
Lb: 0x2
//锁信息
1.5 redo change vactor(重做改变向量)
1.5.1描述table数据块改变改变向量
Kdo op code: urp row
//更新行片
Hdba: ox**** bdba:ox****
//hdba段头块的地址(段地址)
bdba: 块地址
Itli:2
//目前事务使用第二个事务槽
Tabn0 slot 4
//表示更新第一张表,第五行数据
Ncol: 4 nnew:1 size:4
//要更新的记录有4列,更细其中1列,长度增加4;
Col 2 [10 ] 59 59 ….
//更细的为第二列,增加之后长度为10个字符
1.5.2 描述数据块undo动作的undo记录及undo数据块最终变化的重做改变向量
不同于数据库改变向量之处
Ncol: 4 nnew:1 size:-4
//undo的时候,长度减少4
Col 2 [6] 78 78..
//原始数据第二行为 6个字符
--undo块的重做改变向量,描述undo记录的重做改变向量,所以和undo记录的最终值相同。
Dba(数据块地址):ox00..
//undo表空间为数据文件2
记录和undo的记录一样;
1.6 事务的ACDI
1原子性:a进程处理一个事务的中间(改变表1行4的数据),
B
进程访问(表1行4):通过undo记录来访问旧数据。
2 一致性:进程看到的数据为:老状态,新状态,没有中间状态
3 隔离性(独立性):
默认为:提交读;
如a进程,B进程同时修改同一个数据块。
4 持续性:待续;
--改变记录头:change recode header
Op:11.5 表示table redo改变向量
Op:5.2 表示事务的开始,
OP:5.1 表示undo改变向量
OP:5.4 事务结束
--读一致性
(1)数据块需要包含指向undo记录的指针。事务a更新数据,事务b根据指针读取undo记录的原始数据。
(2)事务a1更新一行数据,事务a2更新另外一行数据,则产生两条undo记录,所以数据块(比如包含一个表)要包含2个undo记录的指针,才能保证事务b查询整个表的结果为正常。
(3)oracle在每个数据块内部只允许存放有限的指针(每个队员一个改变块的事务),ITL entries位置
(4)如果事务a对于数据块(一张表)做了两次更新:事务b根据ITL表的entry2找到undo记录2,对事务b隐藏了事务a更新2操作。Undo记录2里面有指针指向ITL表entry1的指针;事务b通过undo记录2
找到 ITL entry1 , 通过ITL entry1
找到undo记录1;
这个事务b读的表的数据,就屏蔽了事务a对于两行的更改;
(5)事务b的内存中生成表的拷贝,然后将事务a的两个undo记录复制应用到拷贝上。
(5)读一致性,针对一个表及这个表的所有undo记录的指针链表
--回滚
(1)回滚是一个事务的历史,需要一个事务所有undo记录的正确排序的指针链表(比如对一行的一列,进行两次操作,产生两台Undo记录);
(2)回滚和读一致性的区别:读一致性的是读内存的数据缓存,读完之后,迅速舍弃。
回滚是获得当前数据块,并且应用undo记录来还原
当前块,表示要写入到磁盘上的版本;
因为是当前块,所有改变要产生redo;
(3)如果undo记录已经被回滚使用,则undo有个标记 user undo applied标记;
-----------------------------------------------------------------------------------------------------------------------------------------------
http://blog.csdn.net/clark_xu 徐长亮专栏原创
__________________________________________________________________________________