Oracle-UNDO表空间解读
UNDO概述官方文档Managing Undo Tablespaces UNDO 表空间用于存放UNDO数据,当执行DML操作(INSERT,UPDATE和DELETE)时,oracle会将这些操作的旧数据写入到UNDO段。 在 oracle9i之前,管理UNDO数据时使用(Rollback Segment)完成的.从oracle9i开始,管理UNDO数据不仅可以使用回滚段,还可以使用UNDO表空间。 10g开始貌似已经不在使用Rollback Segment来管理UNDO数据了,统一使用UNDO表空间。 UNDO数据的作用1,回退事务当执行DML操作修改数据时,UNDO数据被存放到UNDO段,而新数据则被存放到数据段中,如果事务操作存在问题,旧需要回退事务,以取消事务变化. 比如: 用户A执行了语句 >update emp a set a.sal=9999 where a.empno=7788;
>rollback;
当执行ROLLBACK命令时,oracle会将UNDO段的UNDO数据800写回的数据段中. 2,读一致性用户检索数据库数据时,oracle 总是让用户只能看到被提交过的数据(读取提交)或特定时间点的数据(SELECT语句时间点).这样可以确保数据的一致性. 比如: 当用户A执行语句 会话A: SQL> SELECT sal FROM emp WHERE empno=7369;
SAL ---------
800.00
SQL> UPDATE emp SET sal=1000 WHERE empno=7369;
1 row updated
SQL>
会话B(在这里我们通过新开一个SQL窗口来模拟) ,如果还是继续使用会话A,则查询的仍是1000. SQL> SELECT sal FROM emp WHERE empno=7369;
SAL ---------
800.00
3,事务恢复事务恢复是例程恢复的一部分,它是由oracle server自动完成的. 如果在数据库运行过程中出现例程失败(如断电,内存故障,后台进程故障等),那么当重启oracle server时,后台进程SMON会自动执行例程恢复,执行例程恢复时,oracl会重新做所有未应用的记录.回退未提交事务. 4,闪回查询(FlashBack Query)倒叙查询用于取得特定时间点的数据库数据,它是9i新增加的特性,假定当前时间为上午09:00,某用户在上午10:00执行 Oracle10g闪回查询特性的增强Oracle 9i的闪回查询只能提供某个时间点的数据视图,并不能告诉用户这样的数据经过了几个事务、怎样的修改(UPDATE、INSERT、DELETE等),而这些信息在回滚段中是存在的,在Oracle10g中,Oracle进一步加强了闪回查询的特性,提供了以下两种闪回查询:
闪回版本查询允许使用一个新的VERSIONS子句查询两个时间点或者SCN之间的数据版本。这些版本可以按照事务区分,闪回版本查询只返回提交数据,未提交数据不被显示。 Oracle10g的闪回版本查询通过使用VERSIONS子句和对数据表引入一系列的伪列(version_starttime等),可以获得对数据表的所有事务操作,versions_operation代表不同类型的操作(D-DELETE、I_INSERT、U_UPDATE),VERSIONS_XID是一个重要依据,代表了不同版本的事务ID。 Select versions_starttime,versions_endtime,versions_xid,versions_operation,字段xx From table_name versions between timestamp minvalue and maxvalue;
通过以上查询,根据versions_xid可以清晰地区分不同事务在不同时间对数据所作的更改。 由于这个查询需要从Undo中获取前镜像信息,如果Undo中的信息被覆盖,则以上查询将会失败。 数据恢复栗子用户更新了或者误删除了一批数据(假设数据量很大), 下面用一条数据做演示:7369工号的原始工资为800 ,更新后工资为1000 UPDATE emp SET sal=1000 WHERE empno=7369;
此时用户想恢复,假设删除的时间点是2016-11-13 09:00:00 之后,那么我们找到9点之前的 SCN(System Change Number 系统改变号) . SCN提供了Oracle的内部时钟机制,可被看作逻辑时钟,这对于恢复操作是至关重要的. 1.获得当前SCN select timestamp_to_scn(to_timestamp('2016-11-13 09:00:00','YYYY-MM-DD HH24:MI:SS')) as scn from dual ;
select dbms_flashback.get_system_change_number scn from dual; --查询当前数据库的SCN
2.将emp表中的scn点的数据取出 select * from emp AS OF SCN 13267939370491;
可以看到这个时间点之前的数据 7369是800. 3.然后可以根据这个数据进行还原操作 insert into emp select * from emp AS OF SCN 13267939370491;
回滚段著名的ORA-01555问题从应用角度来看ORA-01555
Undo 表空间的两种管理方式Oracle 的 Undo 有两种方式: 一是使用 undo 表空间,二是使用回滚段. 我们通过 undo_management 参数来控制使用哪种方式, 如果设为 auto, 就使用 UNDO 表空间,这时必须要指定一个 UNDO 表空间。 如果设为 manual,系统启动后使用 rollback segment 方式存储 undo 信息。 SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
SQL>
Undo配置参数含义
如果系统没有指定 undo_management,那么系统默认以 manual 方式启动,即使设置了 auto 方式的参数,这些参数将被忽略。 当实例启动的时候,系统自动选择第一个有效的 undo 表空间或者是 rollback 使用 rollback segment当 undo_management 被设置成 MENUAL 时使用系统回滚段,即将 undo records 记录到 SYSTEM 表空间下的 SYSTEM 段。 select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='ROLLBACK';
通过上面的这条语句,我们查到了这个用于 rollback 的 system segment 存在 使用 Undo 表空间当 undo_management 设置成 AUTO 时使用 UNDO tablespace 来管理回滚段这个时候,我们将有多个 undo segment,并且这些 segment 是存放在 UNDO 表空间里的,这样对 DB 的性能就会提高。 select segment_name,next_extent from dba_segments where segment_type='TYPE2 UNDO';
目前我们的这个数据库已经有58个undo segment了。默认的好像是10个。 除了通过dba_segment 表查看的结果, 也可以通过 v
select s.usn,n.name,s.extents,s.hwmsize,s.status from v$rollstat s,v$rollname n where s.usn=n.usn;
undo_retention 和 retention guarantee 参数使用如下SQL 来查看 undo 表空间里空闲和非空闲比例: SELECT tablespace_name,status,SUM (bytes) / 1024 / 1024 "Bytes(M)" FROM dba_undo_extents GROUP BY tablespace_name,status;
UNEXPIRED 和 EXPIRED 是已使用的 undo 表空间, 其中 expired 说明是已经过期的数据,也就是 15 分钟(默认情况)以外的数据,已经被覆盖, 可以认为是空闲的。 在这里就关系到一个参数: UNDO_RETENTION, 该参数用来指定 undo 记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改,通常默认是 900 秒,也就是 15 分钟。 如下所示: SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
SQL>
undo_retention 只是指定 undo 数据的过期时间,并不是说, undo 中的数据一定会在 undo 表空间中保存 15 分钟,比如说刚一个新事务开始的时候,如果undo 表空间已经被写满, 则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期, 因此呢,这就又关联回了第一点,当你创建一个自动管理的 undo 表空间时,还要注意其空间大小,要尽可能保证 undo 表空间有足够的存储空间。 undo_retention 中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被 flashback 特性引用。 如果你的 undo 表空间足够大,而数据库又不是那么繁忙,那么其实undo_retention 参数的值并不会影响到你,哪怕你设置成 1,只要没有事务去覆盖 undo 数据,它就会持续有效。 总之, 要注意 undo 表空间的大小,保证其有足够的存储空间。 只有在一种情况下, undo 表空间能够确保 undo 中的数据在undo_retention指定时间过期前一定有效,就是为 undo 表空间指定 Retention Guarantee,指定之后, oracle 对于 undo 表空间中未过期的 undo 数据不会覆盖. 例如: SQL> Alter tablespace undotbs1 retention guarantee; 禁止 undo 表空间 retention guarantee 总结:
undo 表空间满时的处理方法默认情况下的 Undo_retention 只有 15 分钟,这个默认值,一般都无法满足 SQL> alter system set undo_retention=10800; -- 3 个小时
系统已更改。
当然, undo_retention 设置的越大,所需要的 undo tablespace 也就越大。 这个需要结合自己的系统来设置这个参数。 模拟 UNDO 表空间满的情况SQL> create undo tablespace undo datafile '/oradata/undo.dbf' size 1m;
表空间已创建。
SQL> alter tablespace undo retention guarantee;
表空间已更改。
SQL> alter system set undo_tablespace=undo;
系统已更改。
SQL> create table DBA(id number);
表已创建。
SQL> begin
2 for i in 1 .. 100000 loop
3 insert into dba values(i);
4 commit;
5 end loop;
6 end;
7 /
begin
* 第
1 行出现错误:
ORA-30036: 无法按 8 扩展段 (在还原表空间 'UNDO' 中)
ORA-06512: 在 line 3
解决办法处理方法有两种,
增加数据文件SQL> ALTER TABLESPACE undo ADD DATAFILE '/oradata/undo2.dbf' size 100M reuse;
表空间已更改。
SQL> begin
2 for i in 1..100000 loop
3 insert into dba values(1);
4 commit;
5 end loop;
6 end;
7 /
PL/SQL 过程已成功完成。
切换 UNDO 表空间1、 建立新的表空间 UNDOTBS2 SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE
'/oradata/und3.dbf' size 100M reuse;
表空间已创建。
2、 切换到新建的 UNOD 表空间上来,操作如下 SQL> alter system set undo_tablespace=UNDOTBS2 scope=both;
系统已更改。
3、将原来的 UNDO 表空间,置为脱机: SQL> alter tablespace UNDO offline; 表空间已更改。 4、删除原来的 UNDO 表空间: SQL> drop tablespace UNDO including contents AND DATAFILES CASCADE CONSTRAINTS ;
表空间已删除。
如果只是 drop tablespace UNDO ,则只会在删除控制文件里的记录,并不会物理删除文件。 Drop undo 表空间的时候必须是在未使用的情况下才能进行。如果 undo 表空间正在使用(例如事务失败,但是还没有恢复成功),那么 drop 表空间命令将失败。在 drop 表空间的时候可以使用 including contents。 undo 表空间损坏的处理方法出现 undo 损坏的情况, 大多数是因为异常宕机,在启动的时候报的错误,DB 不能启动。 当 alert log 里出现 ORA-600 + [4194] 时,基本就可以断定,是 undo 表空间出现了损坏。 对于 Undo 损坏的情况,能用备份恢复最好,如果不能,就只能通过一些特殊的方法来恢复。 方法一: 使用 system segment当我们使用 undo 表空间出现损坏时,可以先用 system segment 启动 DB, ( 1) 用 spfile 创建 pfile,然后修改参数: #*.undo_tablespace='UNDOTBS1'
#*.undo_management='AUTO'
#*.undo_tablespace
#*.undo_retention
undo_management='MANUAL'
rollback_segments='SYSTEM'
如何通过SPFILE创建PFILE? SQL> shutdown immediate 数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> create pfile from spfile;
文件已创建。
pfile文件-linux等平台在$ORACLE_HOME/dbs下, ( 2)用修改之后的 pfile,重启 DB SQL> STARTUP MOUNT pfile='F:initorcl.ora' ;
( 3)删除原来的表空间,创建新的 UNDO 表空间 SQL> drop tablespace undotbs;
SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M;
( 4)关闭数据库,修改 pfile 参数,然后用新的 pfile 创建 spfile,在正常启动数据库。 *.undo_tablespace='UNDOTBS1'
*.undo_management='AUTO'
#undo_management='MANUAL'
#rollback_segments='SYSTEM'
创建SPFILE SQL> CREATE SPFILE=$ORACLE_HOME/dbs/spfileSID.ora FROM PFILE $ORACLE_HOME/dbs/initSID.ora
若都使用默认的,则可简写为: SQL> CREATE SPFILE FROM PFILE;
SQL> show parameter spfile
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
spfile string /oracle/product/112/dbs/spfile
cc.ora
方法二: 跳过损坏的 segment在方法一里面,我们使用了 system segment。 通过前面的说明, 我们了解到,undo segment 有多个,我们可以通过 alert log 来查看正在使用的是哪些 segment,这些段有可能损坏了。 我们只需要把这些损坏的 segment 跳过,先正常启动 DB,在创建新的 UNDO 表空间,在切换一下。 ( 1)修改 pfile,添加参数: *._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'
这些字段的值, 我们通过 alert log 查看。 也可以通过如下命令查看: #strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u
( 2)用修改之后的 pfile 启动 DB SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M;
SQL> alter system set undo_tablespace=undotbs1;
SQL> drop tablespace undotbs;
( 4)修改 pfile,创建 spfile,并正常启动 删除: *._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU13$' (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |