undo

Redo中包含undo

DDL操作虽然无法产生rollback,但是仍会产生redoundo

不要对undo数据文件使用自增长,一但使用自增长,undo就不会覆盖。(DBCA创建的DBundodatafile默认是自增长的,需要取消自增长)

Delete产生undo最多,update次之,insert最少(实验过在undo自增长的环境下,delete一张大表增长的undo数据量dba_data_files.bytes和大表所占的dba_segments.bytes一般大

 

1.DDL所产生的undo量视乎其所要维护数据字典的操作类型和操作量.DDL执行失败也产生少量UNDO,因为执行少量递归操作后,Oracle发现所要drop的对象并不存在,将会rollback之前的"部分"递归dml操作。

2.DDL操作产生的REDO是因为DDL修改的字典表和一些段头信息产生的redo

比如:truncate不会有回滚,好像不会产生undo,但是因为对数据字典的操作会有少量undo

需要理解的:无论是DDL还是DML,都是不会真正删除原来数据的,只不过通过不同的方式,让新数据在进入数据块时覆盖掉之前那些删除的数据,truncatedrop通过修改字典数据,delete则会再数据块上打上标记,然后下次新的数据进来会覆盖掉原数据

 

如果delete一张大表时undo不够会报错如下

 

 

 

UNDO数据的作用:

1.回退事务

当执行DML操作修改数据时,UNDO数据被存放到UNDO,而新数据则被存放到数据段中,如果事务操作存在问题,旧需要回退事务,以取消事务变 .假定用户A执行了语句UPDATE emp SET sal=1000 WHERE empno=7788后发现,应该修改雇员7963的工资,而不是雇员7788的工资,那么通过执行ROLLBACK语句可以取消事务变化.当执行 ROLLBACK命令时,oracle会将UNDO段的UNDO数据原sal=800写回的数据段中.

2.读一致性

用户检索数据库数据时,oracle总是使用用户只能看到被提交过的数据(读取提交)或特定时间点的数据(SELECT语句时间点).这样可以确保 数据的一致性.例如,当用户A执行语句UPDATE emp SET sal=1000 WHERE empno=7788,UNDO记录会被存放到回滚段中,而新数据则会存放到EMP段中;假定此时该数据尚未提交,并且用户B执行SELECT sal FROM emp WHERE empno=7788,此时用户B将取得UNDO数据原sal=800,而该数据正是在UNDO记录中取得的.

3.事务恢复

事务恢复是实例恢复的一部分,它是由oracle server自动完成的.如果在数据库运行过程中出现例程失败(如断电,内存故障,后台进程故障等),那么当重启oracle server,后台进程SMON会自动执行例程恢复,执行例程恢复时,oracl会重新做所有未应用的记录.回退未提交事务.

 

 

回滚段中的数据主要分为以下三种:

1.Uncommitted undo information; 未提交的回滚数据,该数据所关联的事务并未提交,用于实现读一致性,所以该数据不能被其它事务的数据所覆盖(假如回滚段不够的情况下,开始执行一个事务,执行到一半就会提示ORA-30036:无法按8扩展段(在还原表空间‘XXXX’),而不会等待该事务一直执行直到commit才报错,就如undo只有10M的情况下,delete一张100M的表,delete执行不到一半就会开始报错了。)

2.Committed undo information;已经提交但未过期的回滚数据,该数据关联的事务已经提交,但是仍受到undo retention参数保持时间的影响

3.Expired undo information;事务已经提交,而且数据保存时间已经超过undo retention参数指定的时间,属于已经过期的数据

当回滚段满了后,会优先覆盖Expired undo information,当过期数据空间用完后,会再覆盖Committed undo information的区域,这时undo retention参数所规定的保持时间会被破坏,Uncommitted undo information的数据是不允许覆盖的,如果要求提交的数据在undo retention参数规定的时间内不会被覆盖,可以在undo表空间上指定RETENTION GUARANTEE

 

 

 

事务具有原子性、一致性、隔离性、持久性(持久化,即写入数据文件)

因为事务的隔离性,所以一个事务的状态,是其他事务无法得知的。一个事务修改数据,但是还没有提交即未结束,其他事务并不知道的,那其他事务为什么不会db buffer中读取,而是去undo中读取。当一个用户对数据进行修改,但是还没有提交时,系统将用户修改的数据的原始信息保存在回滚段中,这样就可以为正在访问相同数据的其他用户提供一份该数据的原始视图,从而保证当前用户未提交的修改信息其他用户无法看到,保证了数据的一致性读

 

一个语句在读取数据快时,如果发现这个数据块是在它读取的过程中被修改的(Buffer Cache中的数据块上都会有最后一次修改数据块时的SCN如果一个事务需要修改数据块中数据,会先在回滚段中保存一份修改前数据和SCN的数据块,然后再更新Buffer Cache中的数据块的数据及其SCN,并标识其为数据。当其他进程读取数据块时,会先比较数据块上的SCN和自己的SCN。如果数据块上的SCN 小于等于进程本身的SCN,则直接读取数据块上的数据;如果数据块上的SCN大于进程本身的SCN,则会从回滚段中找出修改前的数据块读取数据。),就不直接从数据块上读取数据,而是从相应的回滚段条目中读取数据。这就保证了最终结果应该是读操作开始时的那一时刻的快照 (snapshot),而不会受到读期间其他事务的影响。这就是Oracle的一致性读

 

 

 

undo_retention

指定事物commit后在undo 将要保存的时间(),在ORACLE10g中默认的是900秒。udno_retention指定undo数据的过期时间,并不是说undo中的数据一定会在undo表空间中保存15分钟,比如说刚一个新事物开始的时候,如果undo表空间已经被写满,则新事物的数据会自动覆盖已经提交的数据,而不管这些数据是否已过期。undo_retention中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback特性引用。如果你的undo表空间足够大,而数据库又不是那么忙,那么其实undo_retention参数的值并不会影响到你,哪怕你设置成1,只要没有事务覆盖undo数据,它就会持续有效。并不是一个强制参数,undo_retention被忽略的前提:回滚段空间不足和grantee设置为NO

 

GUARANTEE

保证undo_retention参数所设定的时间有效,这个是10g的新功能。Undo_retention一旦设置guarantee这个参数开关,undo_retention就成为一个强依赖参数。Oracle在这种情况下,宁可拒绝SQL DML操作,也不会允许已经提交的但是未过期的undo数据前镜像覆盖的情况发生。

 

UNDO中的数据块,只要数据未提交回滚段未写满(空间足够)或者回滚段未过期(空间足够的情况下保证回滚段未过期回滚事务或强制GUARANTEE)的情况下,旧数据都能被回滚回来。

 

 

了解Oracle在什么情况下会产生ORA-01555:快照过旧错误

假设有一张6000万行数据的testdb表,预计testdb全表扫描1次需要2个小时,参考过程如下:

1、在1点钟,用户A发出了select * from testdb;此时不管将来testdb怎么变化,正确的结果应该是用户A会看到在1点钟这个时刻的内容。

2、在130分,用户B执行了update命令,更新了testdb表中的第4100万行的这条记录,这时,用户A的全表扫描还没有到达第4100万条。毫无疑问,这个时候,第4100万行的这条记录是被写入了回滚段,假设是回滚段UNDOTS1,如果用户A的全表扫描到达了第4100万行,是应该会正确的从回滚段UNDOTS1中读取出1点钟时刻的内容的。

3、这时,用户B将他刚才做的操作提交了,但是这时,系统仍然可以给用户A提供正确的数据,因为那第4100万行记录的内容仍然还在回滚段UNDOTS1里,系统可以根据SCN到回滚段里找到正确的数据,但要注意到,这时记录在UNDOTS1里的第4100万行记录已经发生了重大的改变:就是第4100万行在回滚段UNDOTS1里的数据有可能随时被覆盖掉,因为这条记录已经被提交了!

4、由于用户A的查询时间漫长,而业务在一直不断的进行,UNDOTS1回滚段在被多个不同的transaction使用着,这个回滚段里的extent循环到了第4100万行数据所在的extent,由于这条记录已经被标记提交了,所以这个extent是可以被其他transaction覆盖掉的!

5、到了145分,用户A的查询终于到了第4100万行,而这时已经出现了第4条说的情况,需要到回滚段UNDOTS1去找数据,但是已经被覆盖掉了,这时就出现了ORA-01555错误。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30126024/viewspace-2109197/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30126024/viewspace-2109197/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值