Oracle如何切换temp表空间以及需要注意的点

Oracle如何切换temp表空间以及需要注意的点

昨天有套库报/u01的磁盘90%使用率报警了,无法通过LVM在原盘基础上扩容,计划新增加磁盘并将能在线迁移的相关数据库文件迁移走。

其中,对于temp表空间的处理,我采取的方法实际和undo差不多,均是通过切换来达到目的。

版本是11.0.2.4.0.200714

记录一下遇到的一些问题。

假设现在的临时表空间为temp,我要切换成temp2。

参考mos文档How to Resize the Temporary Tablespace in a Production Environment (文档 ID 160681.1),切换的官方步骤很简单,如下:

1.create temporary tablespace temp2 tempfile '/data/temp02.dbf' size 10g autoextend off;   <------这里文件总大小保持和原临时表空间一致,超过32G需要多个文件
2.alter database default temporary tablespace temp2;
3.alter database tempfile '/u01/app/oracle/oradata/xxxxdb/temp01.dbf' offline; <------官方的语句是"alter tablespace TEMP offline;",这个语法不支持临时表空间,也就是官方给的是错的;另外,有多少个文件就offline多少个
4.drop tablespace TEMP including contents and datafiles;

以上步骤需要注意的是,第2步骤原本我是通过修改当前默认临时表空间为temp的用户,将默认临时表空间修改为temp2。因为可能原来数据库中不止存在temp,甚至可能有临时表空间组。

--以下SQL会生成DCL语句,执行这些语句
select 'alter user '||username||' temporary tablespace temp2;' from dba_users where temporary_tablespace='TEMP';

但是这一步遇到了一个问题,我的库中存在用户"XS$NULL",会导致报错ORA-01031。(如果你的库没有这个用户,则可以用上边的语句这么做)。

17:32:46 SYS@test(201)> alter user XS$NULL temporary tablespace temp2;
alter user XS$NULL temporary tablespace temp2
*
ERROR at line 1:
ORA-01031: insufficient privileges


Elapsed: 00:00:00.00

官方明确指出无法对用户XS$NULL做任何alter user的语句。

如果想要更改默认临时表空间,只能通过上边第2步骤来更改库级别的默认临时表空间,也会同步更改XS$NULL 用户临时表空间。

只是,对于多个临时表空间的库来说(或者多个临时表空间组),会导致所有用户都使用了temp2,需要提前记录用户原来使用的临时表空间情况方便后续还原。

关于用户XS$NULL,这里简单介绍:

XSNULL 是在安装数据库组件 Oracle XML Database (XDB) 时创建的。它是一个内部帐户,表示会话中没有用户。轻量级会话基础结构(APEX 和 XDB 会使用它)会使用它,并且此用户的名称在使用轻量级会话的模块中是硬编码的。因此,XSNULL 必须存在于数据库中。请注意,由于 XSNULL 并不是真正的用户,因此只有 Oracle Database 实例才能访问此帐户。XSNULL 没有任何权限,没有人可以以 XSNULL 的身份进行身份验证,也不能将身份验证凭据分配给 XSNULL。

卸载 XDB 时会删除此帐户。

另外,上边第4步骤执行的时候可能卡住。

https://www.cnblogs.com/PiscesCanon/p/18279318

此时,查询该会话等待事件的信息,如下:

15:38:11 SYS@xxxxdb(597)> select event,status,state,blocking_session from v$session where sid=399;

EVENT                 STATUS  STATE      BLOCKING_SESSION
--------------------- ------- ---------- ----------------
enq: TS - contention  ACTIVE  WAITING                   3

sid为399是执行第4步骤的会话,此时被sid=3的会话卡住,再次查询sid=3的会话信息:
15:38:35 SYS@xxxxdb(597)> select program,event,status,state,blocking_session from v$session where sid=3;

PROGRAM               EVENT                 STATUS  STATE      BLOCKING_SESSION
--------------------- --------------------- ------- ---------- ----------------
oracle@xxxxdb (SMON)  smon timer            ACTIVE  WAITING

根据SMON Blocking Drop Temporary Tablespace (文档 ID 1500044.1)DDL Operations (Alter and Drop) on Temporary Tablespace Hang (文档 ID 1911167.1),可能命中BUG。

BUG特征如下:防。

1.会话等待事件为:"enq: TS - contention",符合。

2.会话被SMON阻塞,符合。

3.阻塞会话的SMON等待事件为"SMON TIMER",符合。

4.数据库版本在11.2.0.3及以上,符合。

官方建议是打上补丁15913577,或者采取临时操作,这里贴上原始英文。

  • Complete all the needed prerequisites (create the new temp tablespace and set as default and no user is assigned to the old tablespace)

  • Bounce the DB

  • Once the DB starts up disconnect from SQLPLUS completely and close the console

  • Open a new console and launch SQLPLUS

  • Run the drop command as the VERY FIRST COMMAND

我试了下临时操作是不行的,后边看了下当前临时段的占用情况,发现旧的临时表空间temp依然被占用着。

16:16:15 SYS@xxxxdb(17)> SELECT s.username,sid,serial#,t.tablespace,contents,sql_address,extents,last_call_et
16:17:23   2      FROM v$session s,v$tempseg_usage t
16:17:23   3  WHERE s.saddr = t.session_addr;

USERNAME                         SID    SERIAL# TABLESPACE      CONTENTS                    SQL_ADDRESS         EXTENTS LAST_CALL_ET
------------------------- ---------- ---------- --------------- --------------------------- ---------------- ---------- ------------
DBSNMP                             8       7869 TEMP            TEMPORARY                   00                        1           22
SYS                              399      34247 TEMP2           TEMPORARY                   00                        1         1386

Elapsed: 00:00:00.00

DBSNMP用户是OEN客户端的会话,重启OEM客户端之后,第4步骤的会话立刻执行完成。

嘶,,,,,,感觉也不像BUG啊。

后续测试了下,新创建的数据库会话一旦执行删除临时表空间的语句时,会在当前临时表空间占用一点临时段空间。

如果是同一个会话操作同时切换两次表空间(比如temp->temp2,temp2->temp),需要注意这个问题。

PS:后边又找了个测试库打补丁,还是不行。只要解决占用问题即可。

相关推荐
夜光小兔纸34 分钟前
oracle查询出表中某几个字段值不唯一的数据
数据库·sql·oracle
deadknight93 小时前
Oracle密码过期处理方式
数据库·oracle
Ljubim.te3 小时前
数据库第01讲章节测验(选项顺序可能不同)
数据库
吱吱喔喔3 小时前
数据分表和分库原理
数据库·分表·分库
快乐非自愿3 小时前
KES数据库实践指南:探索KES数据库的事务隔离级别
数据库·oracle
一只fish3 小时前
Oracle的RECYCLEBIN回收站:轻松恢复误删对象
数据库·oracle
codemami3 小时前
oracle中的nocache的用法和例子
oracle
weixin_440401693 小时前
分布式锁——基于Redis分布式锁
java·数据库·spring boot·redis·分布式
TOR-NADO3 小时前
数据库概念题总结
数据库·oracle
云计算练习生3 小时前
理解MySQL核心技术:存储过程与函数的强大功能
数据库·mysql·存储过程·函数·mysql函数