数据库CONCEPT (二)
-UNDO 表空间研究
Kevin Zou
2011-9-19
在一个数据库中,只能有一个UNDO 表空间。有两种方式来设定的缺省的UNDO 表空间:
1) 在数据库启动过程中,设定初始化参数来设定;
2) 通过ALTER SYSTEM SET UNDO_TABLESPACE 来修改,但这个方法少用;
设定缺省UNDO 表空间的参数:undo_tablespace
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- --------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
第二方法的例子:
SQL> create undo tablespace undo02 datafile 'D:\ORACLE\ORADATA\TEST\undo02.dbf'
size 10M;
表空间已创建。
SQL> select TABLESPACE_NAME, CONTENTS,
2 EXTENT_MANAGEMENT, ALLOCATION_TYPE,
3 SEGMENT_SPACE_MANAGEMENT
4 from dba_tablespaces where contents='UNDO';
TABLESPACE_NAME CONTENTS EXTENT_MAN ALLOCATIO SEGMEN
------------------------------ --------- ---------- --------- ------
UNDOTBS1 UNDO LOCAL SYSTEM MANUAL
UNDO02 UNDO LOCAL SYSTEM MANUAL
SQL> alter system set undo_tablespace ='UNDO02';
系统已更改。
SQL> show parameter undo_tablespace
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace string UNDO02
如果UNDO 表空间中有事务LOG用来事务恢复的,那就不能删除该UNDO 表空间;
在一个SESSION中:
SQL> create undo tablespace undo02 datafile 'D:\ORACLE\ORADATA\TEST\undo02.dbf'
size 5M;
表空间已创建。
SQL> alter system set undo_tablespace ='UNDO02';
系统已更改。
在一个新的session中:
SQL> insert into t values('1','2','3');
已创建 1 行。
回到第一个SESSION中:
SQL> alter system set undo_tablespace ='UNDOTBS1';
系统已更改。
SQL> DROP tablespace undo02;
DROP tablespace undo02
*
第 1 行出现错误:
ORA-30013: 还原表空间 'UNDO02' 当前正在使用中
SQL> select roll.SEGMENT_NAME, rs.CURBLK, rs.status
2 from DBA_ROLLBACK_SEGS roll, V$ROLLSTAT rs
3 where roll.tablespace_name='UNDO02' AND roll.SEGMENT_ID = rs.USN;
SEGMENT_NAME CURBLK STATUS
------------------------------ ---------- ---------------
_SYSSMU20$ 1 PENDING OFFLINE
在有事务的窗口提交事务,再回到第一个窗口上查询(这个可能需要等几秒中才能看到变化:
SQL> select roll.SEGMENT_NAME, rs.CURBLK, rs.status
2 from DBA_ROLLBACK_SEGS roll, V$ROLLSTAT rs
3 where roll.tablespace_name='UNDO02' AND roll.SEGMENT_ID = rs.USN
4 ;
未选定行
SELECT * FROM DBA_ROLLBACK_SEGS
_SYSSMU20$ PUBLIC UNDO02 20
7 153 131072 2 32765
OFFLINE
7
这时UNDO02上的ROLLBACK 段已经OFFLINE,这时可以删除UNDO02 表空间:
SQL> drop tablespace undo02 including contents and datafiles;
表空间已删除。
可能在删除UNDO 表空间时,遇到这样的错误提示:
ORA-01548: active rollback segment 或者 Undo segment shows status as needs recovery.
造成这样的原因是:在UNDO 表空间的DATAFILE已经OFFLINE,因为OFFLINE的数据文件事务不能回滚;或者是UNDO 段自身的任何原因;
例子:
SQL> create undo tablespace undo02 datafile 'D:\ORACLE\ORADATA\TEST\undo03.dbf'
size 10M;
表空间已创建。
SQL> alter system set undo_tablespace ='undo02';
系统已更改。
这时新开启一个SESSION,执行下面的操作:
SQL> insert into t values('1','2','3');
已创建 1 行。
回到第一个SESSION的窗口:
SQL> alter database datafile 'D:\ORACLE\ORADATA\TEST\undo03.dbf' offline;
alter database datafile 'D:\ORACLE\ORADATA\TEST\undo03.dbf' offline
*
第 1 行出现错误:
ORA-00603: ORACLE 服务器会话因致命错误而终止
SQL> select * from v$instance;
ERROR:
ORA-03114: 未连接到 ORALCE
这时会话被提出ORACLE,但是ORACLE还是在运行中。
SQL> conn /as sysdba
已连接。
如果用非SYS用户登录会报错:
SQL> conn kk/kk
ERROR:
ORA-24315: 非法的属性类型
在执行INSERT 语句的窗口中执行:
SQL> conn /as sysdba
ERROR:
ORA-24313: 用户已获得证明
SQL> select count(*) from t;
SP2-0640: 未连接
新开一个窗口用SYSDBA登录,没有发现有异常。
oracle@sjfdcpdb11:~> oerr ora 24313
24313, 00000, "user already authenticated"
// *Cause: A user has already been authenticated on this service handle.
// *Action: Terminate the service context before using it for another user.
oracle@sjfdcpdb11:~> oerr ora 24315
24315, 00000, "illegal attribute type"
// *Cause: An illegal attribute type was specified for the handle.
// *Action: Consult user manual to specify an attribute valid for this handle.
查看文件的状态:
NAME STATUS
---------------------------------------- -------
D:\ORACLE\ORADATA\TEST\SYSTEM01.DBF SYSTEM
D:\ORACLE\ORADATA\TEST\UNDOTBS01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\SYSAUX01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\USERS01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\KK01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\B01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\UNDO03.DBF RECOVER
可以看到UNDO03.DBF需要做RECOVER。
SQL> select count(*) from t;
select count(*) from t
*
第 1 行出现错误:
ORA-00376: 此时无法读取文件 7
ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
因为在UNDO03.DBF offline前,对TBALE T进行插入的操作,而且这个TRANSACTION 没有提交。所以要用到UNDO 表空间来做一致性读。但由于UNDO 数据文件的OFFLINE,这时的读取操作失败。
可以正常对其他对象读取。
SQL> select count(*) from dba_objects;
COUNT(*)
----------
49792
这时整个数据库不接受新的事务,只能做查询。
SQL> insert into t values('1','2','3');
insert into t values('1','2','3')
*
第 1 行出现错误:
ORA-00376: 此时无法读取文件 7
ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
如果这个文件需要做RECOVER,那可以按照下面的步骤来操作:
从文件头找到最后的change number。
SQL> Select file#, checkpoint_change# from v$datafile_header ;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 2106236
2 2106236
3 2106236
4 2106236
5 2106236
6 2106236
7 2111552
从之前的输出,我们可知道undo03.dbf的文件号为7.
查询下需要哪些ARCHIVEDLOG 来做恢复:
SQL> Select sequence#,thread#,name from v$archived_log where 2111552 between first_change# and next_change# ;
未选定行
这说明这个change还没有归档。
可以直接把文件ONLINE:
SQL> conn /as sysdba
已连接。
SQL> select name, status from v$datafile;
NAME STATUS
---------------------------------------- -------
D:\ORACLE\ORADATA\TEST\SYSTEM01.DBF SYSTEM
D:\ORACLE\ORADATA\TEST\UNDOTBS01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\SYSAUX01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\USERS01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\KK01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\B01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\UNDO03.DBF OFFLINE
已选择7行。
SQL> alter database datafile 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF' online;
数据库已更改。
SQL> select name, status from v$datafile;
NAME STATUS
---------------------------------------- -------
D:\ORACLE\ORADATA\TEST\SYSTEM01.DBF SYSTEM
D:\ORACLE\ORADATA\TEST\UNDOTBS01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\SYSAUX01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\USERS01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\KK01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\B01.DBF ONLINE
D:\ORACLE\ORADATA\TEST\UNDO03.DBF ONLINE
这时系统恢复正常。
查看下log:
SMON/PMON都发现了UNDO03.DBF文件异常,首先是SMON写到LOG中,然后PMON开始一直跟踪,知道问题解决。
alter database datafile 'D:\ORACLE\ORADATA\TEST\undo03.dbf' offline
Mon Sep 19 11:37:56 2011
ORA-376 signalled during: alter database datafile 'D:\ORACLE\ORADATA\TEST\undo03.dbf' offline...
Mon Sep 19 11:37:56 2011
Errors in file d:\oracle\product\admin\test\udump\test_ora_4872.trc:
ORA-00376: 此时无法读取文件 7
ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
ORA-00376: 此时无法读取文件 7
ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
ORA-00376: 此时无法读取文件 7
ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
Mon Sep 19 11:37:56 2011
Errors in file d:\oracle\product\admin\test\bdump\test_smon_2648.trc:
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
Mon Sep 19 11:37:57 2011
Errors in file d:\oracle\product\admin\test\bdump\test_smon_2648.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
Mon Sep 19 11:37:59 2011
Errors in file d:\oracle\product\admin\test\udump\test_ora_4872.trc:
ORA-00603: ORACLE server session terminated by fatal error
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
Mon Sep 19 11:38:59 2011
Errors in file d:\oracle\product\admin\test\bdump\test_pmon_4540.trc:
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
Mon Sep 19 11:38:59 2011
Errors in file d:\oracle\product\admin\test\bdump\test_pmon_4540.trc:
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: 'D:\ORACLE\ORADATA\TEST\UNDO03.DBF'
。。。。
这里省略了很多一样的LOG。
和UNDO 表空间相关的视图:
DBA_ROLLBACK_SEGS
V$ROLLNAME
V$ROLLSTAT
DBA_UNDO_EXTENTS
DBA_HIST_UNDOSTAT
V$UNDOSTAT
-THE END-
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/40239/viewspace-707882/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/40239/viewspace-707882/