undo表空间

Posted lriwu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了undo表空间相关的知识,希望对你有一定的参考价值。

undo的作用

使用undo表空间存放从数据文件读出的数据块的前镜像,提供以下4种情况所需的信息:

1.回滚事物:rollback

2.读一致性:当长查询发出后,如果需要保存在undo的前镜像可能需要undo构造CR块

3.实例的恢复:实例恢复(undo—>rollback)

4.闪回技术:flashback query、flashback table等

undo的管理模式

1.manaual 手工:roll segment(淘汰)

2.auto自动:undo tablespace(init parameter:undo_management=auto)

查看undo表空间被哪个表空间激活

SQL>show parameter undo

技术分享图片

 查看undo表空间下的段表

SQL>select * from v$rollname;

技术分享图片

undo表空间管理

1.可以建立多个undo表空间,但一个时刻只有一个处于active;

2.处于active状态的undo tablespace不能offline和drop;

SQL>select tablespace_name,status,contents from dba_tablespace;

技术分享图片

创建undo表空间:开始是100M,空间不够可以自动扩展,直到磁盘被撑爆(一般要给自动扩展的表空间做最大空间限制)

SQL>create undo tablespace undotbs2 datafile ‘/u01/oradata/timran11g/undotbs02.dbf‘ size 100m autoextend on;

原先undotbs01.dbf处于active状态,新添加的undotbs02.dbf是备用:

SQL>select tablespace_name,status,contents from dba_tablespace;

技术分享图片

切换undo表空间:

SQL>alter system set undo_tablespace=‘undotbs2‘;

删除undo表空间:

处于激活状态的undo表空间无法删除:

SQL>drop tablespace undotbs2 including contents and datafiles;

技术分享图片

处于未激活状态的undo表空间可以删除:

SQL>drop tablespace undotbs1 including contents and datafiles;

undo表空间的4种状态

1.active:表示transaction(事物)还没有commit,不可覆盖;

2.unexpired:已经commit,但是还在undo_retention(保留期:单位S)内,不可以覆盖(非强制),加GUARANTEE属性后强制undo_retention内不覆盖。(事物已提交,但是再保留一段时间:1.保证一致性读;2.闪回)

SQL>show parameter undo

技术分享图片

SQL>select tablespace_name,status,contents,retention from dba_tablespaces;

技术分享图片

为表空间设置GUARANTEE属性:

SQL>alter tablespace undotbs2 retention guarantee;

3.expired:已经commit,且时间超过了undo_retention,随时可以覆盖

4.free:分配了但未使用过

undo_retention参数和undo autoextend on特性

undo_retention:参数规定了unexpired commit数据的保留期,它是保证一致性读和大多数闪回技术成功的关键。

10R2以后,只要undo_management参数为auto,oracle会启用undo自动调优(AUM),它根据收集到的数据库中最长查询及撤销生成率自动调整undo_retention。在视图v$undostat中增加了一个字段TUNED_UNDORETENTION(每10分钟计算一次)就是自动调优undo_retention的预估值。如果想关闭AUM,可设置遗憾参数_undo_autotune-false。

将undo表空间设为autoextend on,这是DBCA创建数据库时的缺省设置,这一个特性将在undo空间不足时优先扩展新的空间,其次才是覆盖unexpired commit。如果autoextend on受物理限制不能成功,undo会在noguarantee的情况下盗用unexpired commit的空间,如果盗用不成,oracle报ORA-30036错误:“the specified undo tablespace has no more space available”解决的办法就是增加datafile扩展undo tablespace。另一个关于undo错误是ORA-01555:“rollback records needed by a reader for consistent read are overwritten by other writers” 它是由于无法在undo中构造一致性读时出现的错误。

避免上述报错:undo_managment=auto;打开表空间自动扩展。

SQL>select begin_time,end_time,maxquerylen,tuned_undoretention from v$undostat;

技术分享图片

undo guarantee特性

SQL>select tablespace_name,status,contents,retention from dba_tablespaces;

技术分享图片

guarantee属性随undo表空间建立,可以修改:

SQL>alter tablespace undotbs2 retention guarantee;         //保证在retention期间不允许被覆盖,缺省配置下,undo retention是noguarantee

undo信息的查询

1.v$session   查看用户建立的session,一般来说,一个session同时只能承载一个事务,建立了session未必有事务,只有事务处于活动状态时,v$transaction才能看到这个事务。换句话说,如果看到了事务(在v$transaction 里),那一定有个session和它对应,将两个视图连在一起,信息看的更为清楚。

 SQL>select username,sid,serial# from v$session where username is not null;       //SID和SERIAL#组合可以唯一定位一个session

技术分享图片

2.v$transaction 查看当前处于活跃状态的事物

SQL>select * from v$transaction;

3.v$rollname undo段的名称

SQL>select * from v$rollname;

技术分享图片

 

一般来说,一个session同时只能承载一个事务,建立了session未必有事务,只有事务处于活动状态时,v$transaction才能看到这个事务。换句话说,如果看到了事务(在v$transaction 里),那一定有个session和它对应,将两个视图连在一起,信息看的更为清楚。

示例:

1.打开一个cmd会话s1,scott用户登陆数据库

2.打开另一个会话s2,sys用户登陆数据库,查看此时有多少个会话连接上来

SQL>select username,sid,serial# from v$session where username is not null;

技术分享图片

3.s1会话下产生一个事物

SQL>update emp1 set sal=1000 where empno=7788;

4.查看事物:哪些session上产生哪些事物

SQL>select a.sid,a.serial,a.username,b.xidusn,b.xidslot,b.ubablk,b.status from v$session a,v$transaction b where a.saddr=b.ses_addr;

技术分享图片

//两表联查,sid和serial#在v$session里,在v$transaction里xidusn是undo segment的id,xidslot是事物槽的id,ubablk是undo块号。对照上面看,下面语句显示出——SYSSMU18是一个活动段,与xinusn=18吻合,说明这个段被读进buffer了。

技术分享图片

注意:一个事务只能在一个undo段上扩展,不能跨其它段。

测试:模拟数据库open下的undo数据文件损坏或修复

如果数据库打开时,当前undo坏掉的话,比如现在undotbs2出现了介质损坏,那么数据库就不能继续DML操作。如果这时undotbs2表空间上还有active状态的事物(未提交的事物),oracle会将其下的所有段都标志位NEEDS RECOVERY,这时如果有备份可用恢复这个undotbs2,但如果没有备份,只能使用新建的undo替代损坏的undo,那么损坏undo上未提交的事物也将丢弃。但oracle没有提供自动解决NEEDS RECOVERY的机制,如果想删除这损坏的UNDO表空间,必须另做处理(需要系统择时重启)。下面将举例模拟这种情况:

存在一个事物:

技术分享图片

删除undo表空间的数据文件,再做update操作会报错:

$rm -f undotbs02.dbf

$sqlplus / as sysdba

技术分享图片

SQL>shutdown abort

SQL>startup mount

SQL>select file#,checkpoint_change#,name from v$datafile;

7   968161  /u01/oradata/timran11g/undotbs02.dbf

上述checkpoint_change#从控制文件中读出,底层文件损坏,数据库不知道,所以在这里还能看到undo数据文件;

查看数据文件,这时候undo数据文件删除,所以SCN为0,与上述报错7号文件相同:

SQL>select file#,checkpoint_change#,name from v$datafile_header;

技术分享图片

在mount阶段可以只读控制文件,并不检测SCN一致性,要想打开数据库必须要把7号文件offline:

SQL>alter  database  datafile 7 offline;

数据库已更改

SQL>alter database open;

数据库已更改

这时只有system的undo段,其它段缺失(needs recovery:表示这些段需要修复),无法执行DML操作:

SQL>select * from v$rollname;

USN     NAME

0           SYSTEM

SQL>select segment_name,status from dba_rollback_segs;   //该静态视图可用列出所有(online或offline)undo信息

技术分享图片

新建一个undo表空间:

SQL>create undo tablespace undotbs1 datafile ‘/u01/oradata/timran11g/undotbs01.dbf‘ size 100m autoextend on;

SQL>show parameter undo

技术分享图片

SQL>alter system set undo_tablespace=‘undotbs1‘;

此时提供视图查看undo已经恢复:

SQL>select * from v$rollname;

技术分享图片

提供另外的一个视图会发现原来未提交事物对应的undo段未解决,将导致表被锁定无法对表进行DML操作:

SQL>select * from scott.emp1;

技术分享图片

SQL>select segment_name,status from dba_rollback_segs;  //该静态视图可以列出(online和offline)undo段信息

技术分享图片

删除表空间undotbs2报存在活跃段,无法删除:

SQL>drop tablespace undotbs2 including contents and datafiles;

技术分享图片

解决办法:

解决办法有两个:1.使用备份恢复。2.使用oracle提供的隐含参数_CORRUPTED_ROLLBACK_SEGMENTS。

假设没有备份,使用修改系统隐含参数的方法(即告诉数据库这几个段是坏段)

SQL>create pfile from spfile;

SQL>shutdown abort

#vi /u01/oracle/dbs/inittimran11g.ora   //在静态参数文件里第一行插入以下内容

技术分享图片

然后使用静态参数文件启动数据库

SQL>startup pfile=‘/u01/oracle/dbs/inittimran11g.ora‘

SQL>drop rollback segment ‘_SYSSMU11_1357956213$‘;  //将换段进行删除

SQL>drop rollback segment ‘_SYSSMU12_1357956213$‘; 

.....

此时表空间段处于正常状态:

技术分享图片

此时scott.emp1就可以进行正常的DML操作:

技术分享图片

注意:特殊情况下若还是无法删除undo段,则测试修改字典:

SQL>select * from v$tablespace;  //记下要删除的undo对应的ts#号,比如ts#=2则执行以下语句

SQL>update seg$ set type#=3 where ts#=2;

 

 

以上是关于undo表空间的主要内容,如果未能解决你的问题,请参考以下文章

oracle undo表空间被删除,数据库无法启动,请问如何恢复

undo表空间收缩

ORACLE RAC 11G 添加以及删除UNDO表空间

undo表空间

oracle undo表空间

模拟数据库丢失undo表空间