首页 > Linux操作系统 > Linux操作系统 > Oracle Undo的学习
Rollback是一个代价昂贵的操作,如果一个系统的事务回退率过高,应该检查系统是否正常或者程序设计思路是否存在问题。查询数据库启动依赖的事务回退率,如果发现太高,一定要引起重视。
--查询回退率的sql
SELECT NAME, VALUE
FROM v$sysstat
WHERE NAME IN ('user commits', 'transaction rollbacks');
关于回滚段的数据,如果是delete操作,则回滚段将会记录整个行的数据;如果是update,则只记录被修改字段变化前的数据(前映像);如果是insert,则只记录插入记录的rowid。所以,假如commit,那么回滚段中简单标记该事务已经提交;假如rollback,则操作是delete的话,把回滚段中的数据重新写回数据块,操作是update的话则把变化前的数据修改回去,操作是insert的话则根据rowid把该记录删除。这个过程是保障事务的完整性,保障数据不会丢失。
一致性读(consisitent reads) Oralce的查询集是根据时间点来判定的。Oracle内部通过系统改变号SC作为相对时间点的标准,任何对数据库的改变都会产生SCN,对数据块的数据改变的时候会把该改变所对应的SCN记录在块中。假设查询开始的时候SCN为T,则在查询所扫描的数据块中,如果数据块的COMMIT SCN小于T,则查询接受该数据,如果COMMIT SCN大于T或者说还没有产生COMMIT SCN,则查询会尝试去回滚段中查找数据。这保证了数据的读取时间点的一致性。
在通过回滚段中获取数据的时候,本质上是把数据缓冲区中的数据块做一个拷贝,然后将回滚段中记录的内容恢复到该块中,然后查询使用这个块来进行读取。
系统回滚段和延迟回滚段
SYSTEM回滚段是创建在系统表空间中,主要用于系统级的事务和分配普通事务于其他回滚段上。当手工创建数据后需要创建普通回滚段之前必须首先创建系统回滚段。按oracle文档说,当普通事务异常多的事情可能会使用系统回滚段的情况。正常情况下,系统回滚段主要用于两个方面:一是系统事务,如针对数据字典的操作truncate table 和 drop table。如果truncate or drop table的过程中没有成功,则系统会根据系统回滚段中的数据字典操作信息对该DDL操作进行回退。另一个方面,就是延迟回滚段(Deferred Rollback Segment)。延迟回滚段表示,当我们使一个表空间OFFLINE之后,由于表空间不可用,这个时候若有事务数据位于该空间并执行回滚命令,在client看起来该事务已经回滚,但对于数据块来说回滚并没有真正完成,这个时候数据库将该回滚信息写入系统回滚段(这就是延迟回滚段),等表空间重新ONLINE的时候,数据块从系统回滚段中将回滚信息写入表空间。
回退段的设置和管理
Oracle9i之前需要手动设置回退段,我们需要考虑如下问题:
1.系统并发事务数有多少
2.系统是否存在大查询或者大事务,是否频繁
3.能提供给系统回滚段的表空间的磁盘空间是多少
9i的UNDO TABLESPACE
从9i开始,推荐使用UNDO TABLESPACE,系统自动管理回滚段
Sql> show parameter undo
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
UNDO TABLESPACE变的很大,我们不能缩小,这个时候我们需要考虑创建新的UNDO TABLESPACE,然后换到新的表空间。这时即使UNDO表空间有事务也可以切换,只不过不能立即删除该表空间,切换之后等到原来的表空间中所有的事务处理完毕,并且达到undo_retention的时间后,就可以drop原来的UNDO表空间。
SQL> alter system set undo_tablespace = undotbs02;
System altered.
切换了UNDO表空间后应该修改pfile或者spfile,使得下次启动应用新的UNDO表空间。
回滚段著名的ORA-01555问题
从应用角度来看ORA-01555
1.查询执行时间太长。首先是优化查询,然后考虑在数据块不繁忙的时候运行,最后考虑加大回滚段。
2.过渡频繁的提交。把能够成批提交的单条事务改成成批提交.
3.exp的时候使用consistent = y. 这个参数主要是为了保证在exp的时候使得所有的导出的表在时间点上具有一致性,避免存在主外键关系的表由于不同的时间点的不一致而破坏了数据的完整性。建议该操作在系统空闲的时候进行。
4.由于回滚段回缩导致回滚段还没有循环使用的情况下就出现了回滚段中找不着数据的情况。只能加大回滚段增大optimal设置。
UNDO scripts
查询数据块当前某个session的事务所使用的回滚段大小
SELECT b.SID, a.xidusn, a.xidusn
FROM v$transaction a, v$session b
WHERE a.addr = b.taddr
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9399028/viewspace-686384/ ,如需转载,请注明出处,否则将追究法律责任。