[Oracle OCP 052-2-2]没有备份的情况下undo损坏和修复

system表空间的undo
默认system表空间会有一个单独的undo segment(usn为0)。其他表空间的事务不能使用它。缺省下undo tablespace会被分配10个undo segment,理论上一个段可以有多个事务,但Oracle的策略并不情愿如此,实验表明,对应并发的事务,通常每个事务会分配一个UNDO段,也就是说如果这10个段不够,Oracle会自动在增加段。

当数据库启动时,如果碰到undo数据文件损坏或不同步,可以将其offline,即只有一个系统表空间的undo也能进入系统,使数据字典得以维护,但不能对其他表空间做DML操作。

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

1.模拟undo丢失或损坏

查看当前使用的undo表空间
idle>show parameter undo;
可知当前使用表空间为UNDOTBS2

idle>show parameter undo;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS2
idle>

scott用户下执行一条DML语句
update emp set sal=1000 where empno=7369;

scott@ORCL>update emp set sal=1000 where empno=7369;

1 row updated.

scott@ORCL>

cd到undo文件所存路径,更改undotbs02.dbf文件的文件名,模拟undo文件已丢失的场景
cd /opt/oracle/oradata/orcl
mv undotbs02.dbf undotbs02.bk

[oracle@db01 ~]$ cd /opt/oracle/oradata/orcl
[oracle@db01 orcl]$ ll
total 1649896
-rw-r-----. 1 oracle oinstall   9748480 Jun 26 21:34 con01
-rw-r--r--. 1 oracle oinstall      5787 Jun 26 21:18 con.trace
-rw-r-----. 1 oracle oinstall  10076160 Jul 27 15:06 control01.ctl
-rw-r-----. 1 oracle oinstall 104865792 Jul 27 11:34 example01.dbf
-rw-r-----. 1 oracle oinstall  52429312 Jul 27 15:06 redo01.log
-rw-r-----. 1 oracle oinstall  52429312 Jul 27 11:34 redo02.log
-rw-r-----. 1 oracle oinstall  52429312 Jul 27 11:34 redo03.log
-rw-r-----. 1 oracle oinstall   8389120 Jul 27 11:34 redo04.log
-rw-r-----. 1 oracle oinstall 566239232 Jul 27 15:06 sysaux01.dbf
-rw-r-----. 1 oracle oinstall 723525632 Jul 27 15:05 system01.dbf
-rw-r-----. 1 oracle oinstall  20979712 Jun 26 19:13 temp01.dbf
-rw-r-----. 1 oracle oinstall  52436992 Jul 27 15:05 undotbs02.dbf
-rw-r-----. 1 oracle oinstall  38019072 Jul 27 13:55 users01.dbf
[oracle@db01 orcl]$
[oracle@db01 orcl]$ mv undotbs02.dbf undotbs02.bk
[oracle@db01 orcl]$ ll
total 1649896
-rw-r-----. 1 oracle oinstall   9748480 Jun 26 21:34 con01
-rw-r--r--. 1 oracle oinstall      5787 Jun 26 21:18 con.trace
-rw-r-----. 1 oracle oinstall  10076160 Jul 30 21:43 control01.ctl
-rw-r-----. 1 oracle oinstall 104865792 Jul 30 21:33 example01.dbf
-rw-r-----. 1 oracle oinstall  52429312 Jul 30 21:33 redo01.log
-rw-r-----. 1 oracle oinstall  52429312 Jul 30 21:33 redo02.log
-rw-r-----. 1 oracle oinstall  52429312 Jul 30 21:33 redo03.log
-rw-r-----. 1 oracle oinstall   8389120 Jul 30 21:42 redo04.log
-rw-r-----. 1 oracle oinstall 566239232 Jul 30 21:39 sysaux01.dbf
-rw-r-----. 1 oracle oinstall 723525632 Jul 30 21:38 system01.dbf
-rw-r-----. 1 oracle oinstall  20979712 Jun 26 19:13 temp01.dbf
-rw-r-----. 1 oracle oinstall  52436992 Jul 30 21:40 undotbs02.bk
-rw-r-----. 1 oracle oinstall  38019072 Jul 30 21:40 users01.dbf
[oracle@db01 orcl]$

此时作检查点切换,或回滚都相继报错
检查点切换 : alter system checkpoint;
回滚 :rollback;

scott@ORCL>conn sys/oracle as sysdba;
ERROR:
ORA-02002: error while writing to audit trail
ORA-00604: error occurred at recursive SQL level 1
ORA-01116: error in opening database file 6
ORA-01110: data file 6: '/opt/oracle/oradata/orcl/undotbs02.dbf'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3


Connected.
sys@ORCL>
sys@ORCL>
sys@ORCL>
sys@ORCL>alter system checkpoint;
ERROR:
ORA-03114: not connected to ORACLE


alter system checkpoint
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 6605
Session ID: 1 Serial number: 11


sys@ORCL>

2.解决办法

shutdown 数据库
shutdown immediate; 或 shutdown abort;

idle>shutdown abort;
ORACLE instance shut down.
idle>

重启数据库
startup; 或 startup mount;

idle>startup;
ORACLE instance started.

Total System Global Area  409194496 bytes
Fixed Size                  2213856 bytes
Variable Size             310380576 bytes
Database Buffers           92274688 bytes
Redo Buffers                4325376 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 6 - see DBWR trace file
ORA-01110: data file 6: '/opt/oracle/oradata/orcl/undotbs02.dbf'

//看当前数据库状态
idle>select status from v$instance;

STATUS
------------
MOUNTED

idle>

查看当前undo表空间状态
select * from v$tablespace;
show parameter undo;

idle>select * from v$tablespace;

       TS# NAME                           INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
         0 SYSTEM                         YES NO  YES
         1 SYSAUX                         YES NO  YES
         4 USERS                          YES NO  YES
         6 EXAMPLE                        YES NO  YES
         3 TEMP                           NO  NO  YES
         5 UNDOTBS2                       YES NO  YES

6 rows selected.
idle>show parameter undo;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS2

查看数据文件检查点和数据文件头检查点
select file#,checkpoint_change#,name from v$datafile;(数据文件检查点:记录在控制文件中)
select file#,checkpoint_change# from v$datafile_header;(数据文件头检查点:记录在数据文件中)
由下可知: 数据文件和控制文件的checkpoint_change对不上,一个是1744764,一个是0
数据库开启时,要检查这些检查点是否能对上,对的上,才能正常开启

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

     FILE# CHECKPOINT_CHANGE#
---------- ------------------
NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         1            1744764
/opt/oracle/oradata/orcl/system01.dbf

         2            1744764
/opt/oracle/oradata/orcl/sysaux01.dbf

         4            1744764
/opt/oracle/oradata/orcl/users01.dbf

         5            1744764
/opt/oracle/oradata/orcl/example01.dbf

         6            1744764
/opt/oracle/oradata/orcl/undotbs02.dbf

idle>

idle>select file#,checkpoint_change# from v$datafile_header;

     FILE# CHECKPOINT_CHANGE#
---------- ------------------
         1            1745577
         2            1745577
         4            1745577
         5            1745577
         6                  0

查看表空间的段信息
select * from v$rollname;
报错,查不了

idle>select * from v$rollname;
select * from v$rollname
              *
ERROR at line 1:
ORA-01219: database not open: queries allowed on fixed tables/views only

正常思维是把数据给offline一下
但是这里alter database datafile 6 offline; 不好用了

idle>alter database datafile 6 offline;
alter database datafile 6 offline
*
ERROR at line 1:
ORA-01145: offline immediate disallowed unless media recovery enabled


idle>
idle>
idle>
idle>
idle>alter database datafile 6 offline;
alter database datafile 6 offline
*
ERROR at line 1:
ORA-01145: offline immediate disallowed unless media recovery enabled


idle>
idle>
idle>
idle>alter database UNDOTBS2 offline;
alter database UNDOTBS2 offline
                        *
ERROR at line 1:
ORA-02231: missing or invalid option to ALTER DATABASE


idle>
idle>
idle>alter tablespace UNDOTBS2 offline;
alter tablespace UNDOTBS2 offline
*
ERROR at line 1:
ORA-01109: database not open


idle>alter databse datafile '
  2  ;
alter databse datafile '
      *
ERROR at line 1:
ORA-00940: invalid ALTER command


idle>
idle>
idle>
idle>alter database datafile '/opt/oracle/oradata/undotbs02.dbf' offline;
alter database datafile '/opt/oracle/oradata/undotbs02.dbf' offline
*
ERROR at line 1:
ORA-01516: nonexistent log file, data file, or temporary file "/opt/oracle/oradata/undotbs02.dbf"


idle>alter tablespace UNDOTBS2 offline;
alter tablespace UNDOTBS2 offline
*
ERROR at line 1:
ORA-01109: database not open


idle>

按如下步骤offline drop undotbs02表空间
alter system set undo_management=manual scope=spfile;
shutdown immediate;
startup;
alter database datafile ‘/opt/oracle/oradata/orcl/undotbs02.dbf’ offline drop;

idle>alter system set undo_management=manual scope=spfile;

System altered.

idle>
idle>
idle>
idle>
idle>
idle>shutdown immediate;
ORA-01109: database not open


Database dismounted.
ORACLE instance shut down.
idle>
idle>
idle>
idle>startup;
ORACLE instance started.

Total System Global Area  409194496 bytes
Fixed Size                  2213856 bytes
Variable Size             310380576 bytes
Database Buffers           92274688 bytes
Redo Buffers                4325376 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 6 - see DBWR trace file
ORA-01110: data file 6: '/opt/oracle/oradata/orcl/undotbs02.dbf'


idle>
idle>
idle>
idle>
idle>alter database datafile '/opt/oracle/oradata/orcl/undotbs02.dbf' offline dr                                                                                                                                                          op
  2  /

Database altered.

idle>
idle>
idle>alter database open;

Database altered.

idle>

Reference:
http://www.itpub.net/thread-1812889-1-1.html
在这里插入图片描述

此时再查看rollname
select * from v$rollname;

idle>select * from v$rollname;

       USN NAME
---------- ------------------------------
         0 SYSTEM

idle>

scott用户下此时仍做不了DML操作
update emp set sal=1000;
报错如下

idle>update emp set sal=1000;
update emp set sal=1000
       *
ERROR at line 1:
ORA-00942: table or view does not exist


idle>

sys用户下创建一个undo表空间

idle>create undo tablespace undotbs1 datafile '/opt/oracle/oradata/orcl/undotbs01.dbf' size 100M autoextend on next 50M maxsize unlimited;

Tablespace created.

idle>

查看现在使用的undo表空间
select * from v$tablespace;

idle>select * from v$tablespace;

       TS# NAME                           INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
         0 SYSTEM                         YES NO  YES
         1 SYSAUX                         YES NO  YES
         2 UNDOTBS1                       YES NO  YES
         4 USERS                          YES NO  YES
         6 EXAMPLE                        YES NO  YES
         3 TEMP                           NO  NO  YES
         5 UNDOTBS2                       YES NO  YES

7 rows selected.

idle>

show parameter undo

idle>show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      MANUAL
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS2
idle>

select * from v$rollname;

idle>select * from v$rollname;

       USN NAME
---------- ------------------------------
         0 SYSTEM

idle>

conn scott/tiger;

update emp set sal = 1000

还是报错

scott@ORCL>update emp set sal = 1000;
update emp set sal = 1000
       *
ERROR at line 1:
ORA-01552: cannot use system rollback segment for non-system tablespace 'USERS'


scott@ORCL>

sys用户下执行
select segment_name,status from dba_rollback_segs;
显示needsrecovery

sys@ORCL>select segment_name,status from dba_rollback_segs;

SEGMENT_NAME                   STATUS
------------------------------ ----------------
SYSTEM                         ONLINE
_SYSSMU10_3648379721$          OFFLINE
_SYSSMU9_1275578431$           OFFLINE
_SYSSMU8_3826739819$           OFFLINE
_SYSSMU7_2957964192$           OFFLINE
_SYSSMU6_1108593665$           OFFLINE
_SYSSMU5_1695433794$           OFFLINE
_SYSSMU4_3177103441$           OFFLINE
_SYSSMU3_2393473844$           OFFLINE
_SYSSMU2_2393246700$           OFFLINE
_SYSSMU1_4125566212$           OFFLINE
_SYSSMU20_2343668525$          NEEDS RECOVERY
_SYSSMU19_3332159894$          NEEDS RECOVERY
_SYSSMU18_337899998$           NEEDS RECOVERY
_SYSSMU17_3535887706$          NEEDS RECOVERY
_SYSSMU16_3980642801$          NEEDS RECOVERY
_SYSSMU15_3499720984$          NEEDS RECOVERY
_SYSSMU14_3150185878$          NEEDS RECOVERY
_SYSSMU13_1397975244$          NEEDS RECOVERY
_SYSSMU12_2905439648$          NEEDS RECOVERY
_SYSSMU11_4023443810$          NEEDS RECOVERY

21 rows selected.

sys@ORCL>

刚才undotbs2没有清,里面有执行的事务,

正常来讲应该删掉undotbs2
drop tablespace undotbs2 including contents and datafiles;

sys@ORCL>drop tablespace undotbs2 including contents and datafiles;
drop tablespace undotbs2 including contents and datafiles
*
ERROR at line 1:
ORA-01548: active rollback segment '_SYSSMU11_4023443810$' found, terminate dropping tablespace


sys@ORCL>

但是因为在undo文件丢失之前,undotbs2里面正好有正在执行的事务,所以有needsrecovery的内容,所以删不掉

解决办法:
如果有备份的话就把needs RECOVERY的内容恢复回来
如果没有备份,则使用oracle提供的隐含参数_CORRUPTED_ROLLBACK_SEGMENTS

这里没有备份,我们选择提供的隐含参数_CORRUPTED_ROLLBACK_SEGMENTS方法进行:
建立静态参数文件
SQL>create pfile from spfile;

sys@ORCL>create pfile from spfile;

File created.

sys@ORCL>

SQL>shutdown abort

sys@ORCL>shutdown abort;
ORACLE instance shut down.
sys@ORCL>

在静态参数文件里第一行插入以下内容,然后存盘
vi $ORACLE_HOME/dbs/initorcl.ora

_CORRUPTED_ROLLBACK_SEGMENTS=(_SYSSMU20_2343668525$,_SYSSMU19_3332159894$,_SYSSMU18_337899998$,_SYSSMU17_3535887706$,_SYSSMU16_3980642801$,_SYSSMU15_3499720984$,_SYSSMU14_3150185878$,_SYSSMU13_1397975244$,_SYSSMU12_2905439648$,_SYSSMU11_4023443810$)

在这里插入图片描述
再使静态参数文件启动数据库
startup pfile=’/opt/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora’;

sys@ORCL>startup pfile='/opt/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora';
ORACLE instance started.

Total System Global Area  409194496 bytes
Fixed Size                  2213856 bytes
Variable Size             310380576 bytes
Database Buffers           92274688 bytes
Redo Buffers                4325376 bytes
Database mounted.
Database opened.
sys@ORCL>

依次进行回退段删除
例:
SQL>drop rollback segment “_SYSSMU11_1357956213$”;

sys@ORCL>drop rollback segment "_SYSSMU20_2343668525$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU19_3332159894$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU18_337899998$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU17_3535887706$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU16_3980642801$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU15_3499720984$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU14_3150185878$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU13_1397975244$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU12_2905439648$";

Rollback segment dropped.

sys@ORCL>drop rollback segment "_SYSSMU11_4023443810$";

Rollback segment dropped.

sys@ORCL>

select segment_name,status from dba_rollback_segs;


sys@ORCL>select segment_name,status from dba_rollback_segs;

SEGMENT_NAME                   STATUS
------------------------------ ----------------
SYSTEM                         ONLINE
_SYSSMU10_3648379721$          OFFLINE
_SYSSMU9_1275578431$           OFFLINE
_SYSSMU8_3826739819$           OFFLINE
_SYSSMU7_2957964192$           OFFLINE
_SYSSMU6_1108593665$           OFFLINE
_SYSSMU5_1695433794$           OFFLINE
_SYSSMU4_3177103441$           OFFLINE
_SYSSMU3_2393473844$           OFFLINE
_SYSSMU2_2393246700$           OFFLINE
_SYSSMU1_4125566212$           OFFLINE

11 rows selected.

sys@ORCL>

此时可以正常删除表空间了
SQL> drop tablespace undotbs2 including contents and datafiles;

sys@ORCL>drop tablespace undotbs2 including contents and datafiles;

Tablespace dropped.

sys@ORCL>

如果还删除不了,则尝试修改字典 select * from v$tablespace; 记下要删除的undo对应的ts#号,比如是=2,则执行下行语句: 然后再删除该表空间即可。 update seg$ set type# = 3 where ts#=2

到这里就完成了

发布了58 篇原创文章 · 获赞 5 · 访问量 5128

猜你喜欢

转载自blog.csdn.net/weixin_42161670/article/details/97814154
今日推荐