Oracle一个诡异的临时表空间不足的问题

2022-09-16 14:40:44 浏览数 (1)

一位朋友说他们压测的应用,前几天都正常,昨天执行的时候,报了如下错误,但是今天没出现,DBA说他们某条SQL占用临时表空间太多了,昨天还给扩了10个G的临时表空间容量,

代码语言:javascript复制
ORA-01652: 无法通过 128 (在表空间 TEMP 中)扩展 temp 段

因为牵扯到一些内部数据,所以有些内容就文字叙述,不截图了。

猜测1:SQL导致临时表空间不足?

看了下这条SQL,500多行,大量使用了dblink,但从执行计划看,虽然用到了临时段空间,成本消耗并不大,而且现象是只有昨天出现了这个问题,很难下定论,就是这条SQL导致的。

Oracle的alert.log中会对ORA-01652错误的内容记录trace日志,看了一些,发现其中涉及到很多的SQL,不仅是上述DBA反馈的这条。说明在这个时间段,很多SQL都受影响。

猜测2:用户使用了其他的临时表空间?

因为可以给用户指定不同的临时表空间,是否有可能该用户未使用默认的,而扩容的是默认的临时表空间?

通过检索dba_users,该用户使用的就是默认的临时表空间TEMP,而且该数据库就只有一个临时表空间。

猜测3:临时表空间即使扩容了,确实不够?

看下当前表空间的用度,发现TEMP临时表空间只有300多MB,按上面说的,扩容过10G,现在的容量,应该至少10G以上。

我们还是从alert.log日志中寻找一些端倪。

看到执行扩容的操作,有以下几种,

(1) 第1条"扩容"操作

代码语言:javascript复制
alter tablespace TEMP add datafile '/oradata/xxx/temp01.dbf' size 5G autoextend on maxsize unlimited
ORA-3217 signalled during: alter tablespace TEMP add datafile '/oradata/xxx/temp01.dbf' size 5G autoextend on maxsize unlimited

ORA-3217解释如下,很明显,增加临时表空间的操作存在语法错误,因此扩容失败,

代码语言:javascript复制
03217, 00000, "invalid option for alter of TEMPORARY TABLESPACE"
// *Cause: invalid option for alter of temporary tablespace was specified
// *Action: Specify one of the valid options: ADD TEMPFILE,
//          TEMPFILE ONLINE, TEMPFILE OFFLINE

(2) 第2条"扩容"操作

代码语言:javascript复制
alter tablespace tempfile add datafile '/oradata/xxx/temp01.dbf' size 5G autoextend on maxsize unlimited
ORA-959 signalled during: alter tablespace tempfile add datafile '/oradata/xxx/temp01.dbf' size 5G autoextend on maxsize unlimited

ORA-959解释如下,不存在tempfile这个名称的临时表空间,

代码语言:javascript复制
00959, 00000, "tablespace '%s' does not exist"
// *Cause:
// *Action:

(3) 第3条"扩容"操作

代码语言:javascript复制
alter database datafile '/oradata/xxx/temp01.dbf' autoextend on
ORA-1516 signalled during: alter database datafile '/oradata/xxx/temp01.dbf' autoextend on


alter database datafile '/oradata/xxx/temp02.dbf' autoextend on
ORA-1516 signalled during: alter database datafile '/oradata/xxx/temp02.dbf' autoextend on

ORA-1516解释如下,前半部分的语法是错误的,

代码语言:javascript复制
01516, 00000, "nonexistent log file, data file, or temporary file "%s" in the current container"
// *Cause:  An attempt was made to use ALTER DATABASE to rename
//          a log file, data file, or temporary file; or to change attributes
//          of a data file or temporary file (for example, resize, autoextend,
//          online or offline); or to re-create or move a data file.
//          The attempt failed because the specified file
//          is not known to the database's control file
//          or the current container or is not of a type
//          supported by the request.
// *Action: Specify the name or number of an existing file
//          of the correct type, as appropriate.
//          Check the relevant V$ table for a list of possible files.

(4) 第4条"扩容"操作

代码语言:javascript复制
alter tablespace temp add tempfile '/oradata/xxx/temp01.dbf' size 5G
ORA-1537 signalled during: alter tablespace temp add tempfile '/oradata/xxx/temp01.dbf' size 5G

ORA-1537解释如下,temp01.dbf数据文件就是当前临时表空间TEMP所对应的文件,因此增加该文件,会提示重复,

代码语言:javascript复制
01537, 00000, "cannot add file '%s' - file already part of database"
// *Cause:  During CREATE or ALTER TABLESPACE, a file being added is already
//         part of the database.
// *Action:  Use a different file name.

几次增加临时表空间的操作,都是因为各种原因没加成,直到执行了这条,

代码语言:javascript复制
alter tablespace temp add tempfile '/oradata/xxx/temp02.dbf' size 10G
Completed: alter tablespace temp add tempfile '/oradata/xxx/temp02.dbf' size 10G

所以在未增加成功之前,猜测确实临时表空间是不足的,因为很多应用共用这个临时表空间,所以受影响的SQL应该有很多,而这个应用反馈的语句,只是其中之一,当增加成功后,才会恢复正常,从alert.log看,确实没继续抛出这个异常了。

但是,既然增加了10G的空间了,为什么开始检索的时候,临时表空间容量只有300MB?还是从alert.log找线索,他执行了这条,对临时表空间

代码语言:javascript复制
alter tablespace temp shrink space
Completed: alter tablespace temp shrink space

之前理解,一般只是对表才能做shrink space,起到收缩空间的作用,但这个是对表空间执行的,实际上官方文档,提到了这种操作,特意指出"Shrink the amount of space a temporary tablespace or a temp file is taking",对临时表空间才会起作用,

SHRINK SPACE Clause This clause is valid only for temporary tablespaces. It lets you reduce the amount of space the tablespace is taking. In the optional KEEP clause, the size_clause defines the lower bound that a tablespace can be shrunk to. It is the opposite of MAXSIZE for an autoextensible tablespace. If you omit the KEEP clause, then the database will attempt to shrink the tablespace as much as possible as long as other tablespace storage attributes are satisfied Managing Space in a Temporary Tablespace: Example The following statement manages the space in the temporary tablespace created in "Creating a Temporary Tablespace: Example" using the SHRINK SPACE clause. The KEEP clause is omitted, so the database will attempt to shrink the tablespace as much as possible as long as other tablespace storage attributes are satisfied. ALTER TABLESPACE temp_demo SHRINK SPACE;

P.S.https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_3002.htm#SQLRF01002

因此,临时表空间的容量实际被收缩了。

针对这个案例,能借鉴到的还是很多的,当出现问题时,除了一些常规的判断路径外,还可以大胆猜测,逐一论断。

0 人点赞