发现哪些进程/查询正在使用 Oracle 临时表空间

发布于 2024-07-06 23:06:13 字数 380 浏览 6 评论 0原文

Oracle FAQ 定义临时表空间如下:

临时表空间用于 管理数据库排序空间 操作和存储全局 临时表。 例如,如果您 连接两个大表,和 Oracle 无法在内存、空间中进行排序 将被临时分配 用于进行排序的表空间 操作。

太好了,但我需要更多有关该空间的具体用途的详细信息。 由于应用程序设计的怪癖,大多数查询都会进行某种排序,因此我需要将其范围缩小到客户端可执行文件、目标表或 SQL 语句。

本质上,我正在寻找线索来更准确地告诉我这个(相当大的应用程序)可能出了什么问题。 任何类型的线索都可能有用,只要它比“排序”更精确即可。

Oracle FAQ defines temp table space as follows:

Temporary tablespaces are used to
manage space for database sort
operations and for storing global
temporary tables. For example, if you
join two large tables, and Oracle
cannot do the sort in memory, space
will be allocated in a temporary
tablespace for doing the sort
operation.

That's great, but I need more detail about what exactly is using the space. Due to quirks of the application design most queries do some kind of sorting, so I need to narrow it down to client executable, target table, or SQL statement.

Essentially, I'm looking for clues to tell me more precisely what might be wrong with this (rather large application). Any sort of clue might be useful, so long as it is more precise than "sorting".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

恬淡成诗 2024-07-13 23:06:14

我不确定您必须提供哪些信息,但使用以下查询将指出哪些程序/用户/会话等当前正在使用您的临时空间。

SELECT   b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , ROUND (  (  ( b.blocks * p.VALUE ) / 1024 / 1024 ), 2 ) size_mb
       , a.SID
       , a.serial#
       , a.username
       , a.osuser
       , a.program
       , a.status
    FROM v$session a
       , v$sort_usage b
       , v$process c
       , v$parameter p
   WHERE p.NAME = 'db_block_size'
     AND a.saddr = b.session_addr
     AND a.paddr = c.addr
ORDER BY b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , b.blocks;

一旦您发现哪个会话造成了损害,请查看正在执行的 SQL,您应该走在正确的道路上。

I'm not sure exactly what information you have to hand already, but using the following query will point out which program/user/sessions etc are currently using your temp space.

SELECT   b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , ROUND (  (  ( b.blocks * p.VALUE ) / 1024 / 1024 ), 2 ) size_mb
       , a.SID
       , a.serial#
       , a.username
       , a.osuser
       , a.program
       , a.status
    FROM v$session a
       , v$sort_usage b
       , v$process c
       , v$parameter p
   WHERE p.NAME = 'db_block_size'
     AND a.saddr = b.session_addr
     AND a.paddr = c.addr
ORDER BY b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , b.blocks;

Once you find out which session is doing the damage, then have a look at the SQL being executed, and you should be on the right path.

南渊 2024-07-13 23:06:14

感谢 Michael OShea 的回答,

但如果您有 Oracle RAC 多个实例,那么您将需要这个......

SELECT   b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , ROUND (  (  ( b.blocks * p.VALUE ) / 1024 / 1024 ), 2 ) size_mb
       , a.inst_ID
       , a.SID
       , a.serial#
       , a.username
       , a.osuser
       , a.program
       , a.status
    FROM gv$session a
       , gv$sort_usage b
       , gv$process c
       , gv$parameter p
   WHERE p.NAME = 'db_block_size'
     AND a.saddr = b.session_addr
     AND a.paddr = c.addr
     -- AND b.TABLESPACE='TEMP2'
ORDER BY a.inst_ID , b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , b.blocks;

以及这个脚本来生成终止语句:
请检查您将杀死哪些会话...

SELECT  b.TABLESPACE, a.username , a.osuser , a.program , a.status ,
       'ALTER SYSTEM KILL SESSION '''||a.SID||','||a.SERIAL#||',@'||a.inst_ID||''' IMMEDIATE;'
    FROM gv$session a
       , gv$sort_usage b
       , gv$process c
       , gv$parameter p
   WHERE p.NAME = 'db_block_size'
     AND a.saddr = b.session_addr
     AND a.paddr = c.addr
     -- AND b.TABLESPACE='TEMP'
ORDER BY a.inst_ID , b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , b.blocks;

Thanks goes for Michael OShea for his answer ,

but in case you have Oracle RAC multiple instances , then you will need this ...

SELECT   b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , ROUND (  (  ( b.blocks * p.VALUE ) / 1024 / 1024 ), 2 ) size_mb
       , a.inst_ID
       , a.SID
       , a.serial#
       , a.username
       , a.osuser
       , a.program
       , a.status
    FROM gv$session a
       , gv$sort_usage b
       , gv$process c
       , gv$parameter p
   WHERE p.NAME = 'db_block_size'
     AND a.saddr = b.session_addr
     AND a.paddr = c.addr
     -- AND b.TABLESPACE='TEMP2'
ORDER BY a.inst_ID , b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , b.blocks;

and this the script to generate the kill statements:
Please review which sessions you will be killing ...

SELECT  b.TABLESPACE, a.username , a.osuser , a.program , a.status ,
       'ALTER SYSTEM KILL SESSION '''||a.SID||','||a.SERIAL#||',@'||a.inst_ID||''' IMMEDIATE;'
    FROM gv$session a
       , gv$sort_usage b
       , gv$process c
       , gv$parameter p
   WHERE p.NAME = 'db_block_size'
     AND a.saddr = b.session_addr
     AND a.paddr = c.addr
     -- AND b.TABLESPACE='TEMP'
ORDER BY a.inst_ID , b.TABLESPACE
       , b.segfile#
       , b.segblk#
       , b.blocks;
紫南 2024-07-13 23:06:14

一个经验法则是,几乎任何花费超过一秒的查询都可能使用一些 TEMP 空间,这些不仅仅是涉及 ORDER BY 的查询,还包括:

  1. GROUP BY(10.2 之前的 SORT GROUPBY 和 10.2 以后的 HASH GROUPBY)
  2. HASH JOIN或 MERGE JOIN
  3. 全局临时表(显然)
  4. 索引重建

有时,临时表空间中的已用空间不会被 Oracle 释放(错误/怪癖),因此您需要手动从表空间中删除文件,从文件系统中删除它并创建另一个。

One rule of thumb is that almost any query that takes more than a second probably uses some TEMP space, and these are not the just ones involving ORDER BYs but also:

  1. GROUP BYs (SORT GROUPBY before 10.2 and HASH GROUPBY from 10.2 onwards)
  2. HASH JOINs or MERGE JOINs
  3. Global Temp Tables (obviously)
  4. Index rebuilds

Occasionally, used space in temp tablespaces doesn't get released by Oracle (bug/quirk) so you need to manually drop a file from the tablespace, drop it from the file system and create another one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文