zoukankan      html  css  js  c++  java
  • How to Release the Temp LOB Space and Avoid Hitting ORA-1652 (文档 ID 802897.1)

    APPLIES TO:

    Oracle Database - Enterprise Edition - Version 8.1.5.0 and later
    Information in this document applies to any platform.

    GOAL

    How to release Temp LOB Segment that has been created explicitly or implicitly by Oracle for intermediate stages of database processing.

    SOLUTION

    Prior to 10.2.0.4 
    =============


    Actually we have different kinds of Temporary Segments. Oracle often requires temporary work space for intermediate stages of database processing. There are different kinds of temporary segments in the database. Some of them are created explicitly by the users. The others are created and accessed for the user by the system.

    Use the view V$TEMPORARY_LOBS in conjunction with DBA_SEGMENTS or V$SORT_SEGMENT to determine how much space is being used by temporary lobs. We can create an explicit temporary BLOB or CLOB and its corresponding index in the user's default tablespace calling DBMS_LOB.CREATETEMPORARY procedure, and free them by calling DBMS_LOB.FREETEMPORARY.

    When calling DBMS_LOB.CREATETEMPORARY, TWO temporary extents are allocated to store LOB_DATA and one temporary extent to store LOB_INDEX in 8i. So, a total of three temporary extents are allocated in 8i. However, in 9i (Release 2) and up, only one temporary extent is allocated .

    DBMS_LOB.CREATETEMPORARY can be used with limited success prior to 10.2.0.4. 

    The only true solution prior to 10.2.0.4 and the setting of the event (as discussed below) is to terminate the session that created the temporary lob.

    10.2.0.4 and above 
    ===============


    Two approaches are available:

    1- You can use DBMS_LOB.FREETEMPORARY where the LOB locator that was freed is marked as invalid. 

    DBMS_LOB.FREETEMPORARY frees space from temp tablespace and it is available to that same session, but the temp segment is not released and made available to other sessions. So if the session creates another temp lob after freetemporary, the space is reused by that session.
    The space is not released until the session exits. That can easily lead to an ORA-1652 error when multiple concurrent sessions are doing a huge LOB operations and not exiting, thus the freed space by DBMS_LOB.FREETEMPORARY is only available within the calling session but not for the other sessions.

    -- ========
    -- Session1
    -- ========
    -- SQL*Plus: Release 10.2.0.4.0 - Production on Tue Apr 7 09:06:31 2009

    -- Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


    -- Connected to:
    -- Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
    -- With the Partitioning, OLAP, Data Mining and Real Application Testing options

    declare
      clb clob;
      ch varchar2(32767);
      k number;
    begin
      dbms_lob.createtemporary(clb,true,dbms_lob.call);
        for i in 1..1500 loop
          ch:=lpad('o',32767,'Y');
          dbms_lob.writeappend(clb,length(ch),ch);
        end loop;
        k:=dbms_lob.getlength(clb);
        dbms_lob.freetemporary(clb);
        dbms_output.put_line('the clob length: '||k);
    end;
    /

    -- PL/SQL procedure successfully completed.

    select u.tablespace, u.contents, u.segtype, u.extents, u.blocks, round(((u.blocks*P.VALUE)/1024/1024),2) MB
    from v$session s, v$sort_usage u, SYS.V_$SYSTEM_PARAMETER P
    where s.saddr = u.session_addr 
    AND UPPER(P.NAME)='DB_BLOCK_SIZE'
    order by MB DESC;
    TABLESPACE                      CONTENTS  SEGTYPE      EXTENTS     BLOCKS         MB
    ------------------------------- --------- --------- ---------- ---------- ----------
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_INDEX          1        128          1
    TEMP                            TEMPORARY LOB_INDEX          1        128          1
    declare
      clb clob;
      ch varchar2(32767);
      k number;
    begin
      dbms_lob.createtemporary(clb,true,dbms_lob.call);
      for i in 1..1500 loop
        ch:=lpad('o',32767,'Y');
        dbms_lob.writeappend(clb,length(ch),ch);
      end loop;
      k:=dbms_lob.getlength(clb);
      dbms_lob.freetemporary(clb);
      dbms_output.put_line('the clob length: '||k);
    end;
    /

    -- PL/SQL procedure successfully completed.

    select u.tablespace, u.contents, u.segtype, u.extents, u.blocks, round(((u.blocks*P.VALUE)/1024/1024),2) MB
    from v$session s, v$sort_usage u, SYS.V_$SYSTEM_PARAMETER P
    where s.saddr = u.session_addr
    and    UPPER(P.NAME)='DB_BLOCK_SIZE'
    order by MB DESC;
    TABLESPACE                      CONTENTS  SEGTYPE      EXTENTS     BLOCKS         MB
    ------------------------------- --------- --------- ---------- ---------- ----------
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_INDEX          1        128          1
    TEMP                            TEMPORARY LOB_INDEX          1        128          1

    <<<<<<<<<<<<< Only 4 rows selected >>>>>>>>>>>>>>>>
    -- =========
    -- session2
    -- =========

    declare
      clb clob;
      ch varchar2(32767);
      k number;
    begin
      dbms_lob.createtemporary(clb,true,dbms_lob.call);
      for i in 1..1500 loop
        ch:=lpad('o',32767,'Y');
        dbms_lob.writeappend(clb,length(ch),ch);
      end loop;
      k:=dbms_lob.getlength(clb);
      dbms_lob.freetemporary(clb);
      dbms_output.put_line('the clob length: '||k);
    end;
    /

    -- PL/SQL procedure successfully completed.

    select u.tablespace, u.contents, u.segtype, u.extents, u.blocks, round(((u.blocks*P.VALUE)/1024/1024),2) MB
    from v$session s, v$sort_usage u, SYS.V_$SYSTEM_PARAMETER P
    where s.saddr = u.session_addr
    and    UPPER(P.NAME)='DB_BLOCK_SIZE'
    order by MB DESC;
    TABLESPACE                      CONTENTS  SEGTYPE      EXTENTS     BLOCKS         MB
    ------------------------------- --------- --------- ---------- ---------- ----------
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_INDEX          1        128          1
    TEMP                            TEMPORARY LOB_INDEX          1        128          1
    TEMP                            TEMPORARY LOB_INDEX          1        128          1

    6 rows selected.
    -- When we disconnect session 2 now and run the same query from session 1 again we will get 4 rows only

    select u.tablespace, u.contents, u.segtype, u.extents, u.blocks, round(((u.blocks*P.VALUE)/1024/1024),2) MB
    from v$session s, v$sort_usage u, SYS.V_$SYSTEM_PARAMETER P
    where s.saddr = u.session_addr
    and UPPER(P.NAME)='DB_BLOCK_SIZE'
    order by MB DESC;
    TABLESPACE                      CONTENTS  SEGTYPE      EXTENTS     BLOCKS         MB
    ------------------------------- --------- --------- ---------- ---------- ----------
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_DATA          48       6144         48
    TEMP                            TEMPORARY LOB_INDEX          1        128          1
    TEMP                            TEMPORARY LOB_INDEX          1        128          1


    2-Exiting the session where are the TEMP segments will be freed completely.


    10.2.0.4 and above
    ===============

    In addition to the above approaches For 10.2.0.4 and above a new event introduced (event 60025) where when set if there are no active temp lobs in the session (ie: both cache temp lob and no-cache temp lobs used are zero) then the temp segment itself will also be freed releasing the space for other sessions to use. Note that this change is disabled by default. You can set this using alter system in the system level also.

    alter session set events '60025 trace name context forever';
  • 相关阅读:
    用DeBug的方式,带你掌握HBase文件在Snapshot的各种变化
    业务随行:用户的网络访问策略还能这么玩
    清明节特辑 |记忆存储、声音还原、性格模仿……AI可以让人类永生吗?
    答题拿奖两不误:华为云知乎金牌答题官,就是你!
    一文掌握GaussDB(DWS) SQL进阶技能:全文检索
    LiteOS内核源码分析:任务栈信息
    INTERSPEECH2020 语音情感分析论文之我见
    统一元数据,数据湖Catalog让大数据存算分离不再是问题
    云图说|将源端MongoDB业务搬迁至华为云DDS的几种方式
    跟我学丨如何用鲲鹏服务器搭建Hadoop全分布式集群
  • 原文地址:https://www.cnblogs.com/future2012lg/p/4528333.html
Copyright © 2011-2022 走看看