【问题标题】:Discover what process/query is using oracle temp tablespace发现什么进程/查询正在使用 oracle 临时表空间
【发布时间】:2010-09-15 12:58:36
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: oracle debugging performance statistics oracleinternals


    【解决方案1】:

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

    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,你应该走在正确的道路上。

    【讨论】:

      【解决方案2】:

      一个经验法则是,几乎所有耗时超过一秒的查询都可能使用一些 TEMP 空间,而且这些不仅仅是涉及 ORDER BY 的查询,还有:

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

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

      【讨论】:

      • 所有这些都会被记录 v$sort_usage 吗?
      • 根据 Oracle 文档,V$TEMPSEG_USAGE 包含所有需要 TEMP 空间的不同操作。
      【解决方案3】:

      感谢 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;
      

      这是生成kill语句的脚本: 请查看您将要终止的会话...

      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;
      

      【讨论】:

      • 这是黄金。谢谢!
      • 实例 ID 没有连接,导致记录倍增
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      • 1970-01-01
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多