首页 > 数据库 > Oracle > Undo Tablespace 切换注意事项
oracle中经常遇到undo表空间不释放,如果设置了unod表空间自动扩展AUTOEXTEND ON则还有可能把磁盘撑爆。当undo被撑满了,经常会选择重建undo表空间,进行切换。虽然切换undo比较容易,但如果要在生产切换undo还是考虑的周到一些比较好。
注意事项:
1. 检查系统使用的参数文件是pfile还是spfile。
如果用pfile记得修改pfile中的undo_tablespace参数。否则容易导致下次重启数据库时找不到历史的undo表空间而启动失败。
|
select name , value from v$parameter where name='spfile'; |
2. 切换undo时检查是否还有事务存在。如果有事务,在删除旧undo时可能会遇到ORA-30013的错误。
|
select count(*) from v$transaction; |
3. 检查undo对应的数据文件是否被真正删除。
摘自:How to Shrink the datafile of Undo Tablespace [ID 268870.1]
NOTE: Dropping the old tablespace may give ORA-30013 : undo tablespace '%s' is currently in use. This error indicates you must wait for the undo tablespace to become unavailable. In other words, you must wait for existing transaction to commit or rollback. Also be aware that on some platforms, disk space is not freed to the OS until the database is restarted. The disk space will remain "allocated" from the OS perspective until the database restart.
4. 虽然可以在线切换undo,但切换后如果能重启一下最好。以免留下后患。或者选择在可以重启的时候去切换undo。
切换undo的步骤:
一、检查undo设置
|
SQL> show parameter undo |
二、查看undo表空间的大小
|
SELECT D.TABLESPACE_NAME,D.FILE_NAME, SUM(D.BYTES) / 1024 / 1024 MB |
三、检查参数文件类型
|
select name , value from v$parameter where name='spfile'; |
四、创建undo表空间
|
SQL> create undo tablespace UNDOTBS2 datafile 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL2/UNDOTBS02.DBF' size 500M; |
五、等待原undo表空间UNDO SEGMENT OFFLINE后可以切换undo
|
SQL> SELECT USN, 2 XACTS, 3 STATUS, 4 RSSIZE / 1024 / 1024 / 1024 RSSIZE, 5 HWMSIZE / 1024 / 1024 / 1024 HWMSIZE, 6 SHRINKS 7 FROM V$ROLLSTAT 8 ORDER BY RSSIZE; |
六、切换UNDO表空间
|
SQL>alter system set undo_tablespace=undotbs2 scope=both; |
七、删除UNDO表空间及数据文件
|
SQL>drop tablespace UNDOTBS1 including contents and datafiles; |
注意:
可通过下列语句查看事务及连接信息:
SELECT a.usn, a.name, b.status, c.tablespace_name, d.addr, e.sid, e.serial#, e.username, e.program, e.machine, e.osuser
FROM v$rollname a, v$rollstat b, dba_rollback_segs c, v$transaction d, v$sessione
WHERE a.usn=b.usn AND a.name=c.segment_name AND a.usn=d.xidusn AND d.addr=e.taddr AND b.status='PENDING OFFLINE';
通过下列语句kill掉相应的用户进程,让事务回滚:
ALTER SYSTEM KILL SESSION '
通过如下两条语句查询存在问题的分布式事务:
SELECT KTUXEUSN, KTUXESLT, KTUXESQN, --这几个字段表示事务ID,其中第一个表示回滚段,如7 5 311977,则事务ID为7.5.311977
KTUXESTA Status,KTUXECFL Flags
FROM x$ktuxe WHERE ktuxesta!='INACTIVE';
查看结果中存在状态为prepare的记录。
SELECT LOCAL_TRAN_ID,STATE FROM DBA_2PC_PENDING;
查看结果中存在状态为prepare的记录。
存在三种情况:1. 事务ID在x$ktuxe中存在,但DBA_2PC_PENDING中没有;2.事务ID在x$ktuxe中不存在,但在DBA_2PC_PENDING中存在;3.在两者中都存在。对于这三种情况分别采用下面三种方法进行清除:
1)事务ID在x$ktuxe中存在,但DBA_2PC_PENDING中没有:
alter system disable distributed recovery;
insert into pending_trans$ (
LOCAL_TRAN_ID,
GLOBAL_TRAN_FMT,
GLOBAL_ORACLE_ID,
STATE,
STATUS,
SESSION_VECTOR,
RECO_VECTOR,
TYPE#,
FAIL_TIME,
RECO_TIME)
values( '7.5.311977', --<== replaced by your transaction ID
306206,
'XXXXXXX.12345.1.2.3',
'prepared','P',
hextoraw( '00000001' ),
hextoraw( '00000000' ),
0, sysdate, sysdate );
insert into pending_sessions$
values( '7.5.311977', --<== replaced by your transaction ID */
1, hextoraw('05004F003A1500000104'), 'C', 0, 30258592, '', 146);
commit;
commit force '7.5.311977'; --<== replaced by your transaction ID
alter system enable distributed recovery;
commit;
exec dbms_transaction.purge_lost_db_entry( '7.5.311977' ); --<== replaced by your transaction ID
commit;
以上语句建议采用sqlplus / as sysdba本地进行操作,否则可能出现错误。
2)事务ID在x$ktuxe中不存在,但在DBA_2PC_PENDING中存在:
直接清除掉dba_2pc_pending中记录即可
set transaction use rollback segment SYSTEM;
delete from sys.pending_trans$ where local_tran_id ='7.5.311977';
delete from sys.pending_sessions$ where local_tran_id ='7.5.311977';
delete from sys.pending_sub_sessions$ where local_tran_id ='7.5.311977';
commit;
3)在两者中都存在
采用手工删除掉dba_2pc_pending中记录,然后按照第一种情况处理。
即先执行2)中步骤,然后执行1)中步骤。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29424472/viewspace-1256645/ ,如需转载,请注明出处,否则将追究法律责任。