ORA-01652 無法透過128 (在表空間 TEMP中)擴充套件temp段

Iven_lin發表於2024-04-10

1,同事說執行sql報錯

同事在plsql裡面執行sql報錯,報錯資訊:ora-01652 無法透過128 (在表空間 TEMP中)擴充套件temp段,如下圖所示:

2,檢視報錯sql語句
Sql比較長,而且無法擴充套件temp欄位,那麼基本推斷可能有如下2種情況:

(1)oracle的temp臨時表空間太小了;

(2)一個效能非常差的笛卡爾積的帶全表掃描的sql佔用的資源超過了temp的表空間大小。

先看執行的sql語句,sql比較長,所以這種屬於(1)(2)的結合情況了,sql如下:

異常語句:

ORA-01652 無法透過128 (在表空間 TEMP中)擴充套件temp段
SELECT
        HOU.name                    ou_name
        ,fnd_flex_xml_publisher_apis.process_kff_combination_1('FLEX_SELECT_ALL', 'SQLGL', 'GL#', gcc.CHART_OF_ACCOUNTS_ID, NULL, gcc.CODE_COMBINATION_ID, 'ALL', 'Y', 'VALUE')            accounts
        ,AI.invoice_currency_code      transaction_currency
        ,AS1.vendor_name               supplier_name
        ,AI.invoice_id              invoice_id_tag
        ,AI.invoice_num                invoice_number
        ,AI.invoice_date              invoice_date
        ,NVL(AI.exchange_rate,1)    inv_exch_rate
        ,NVL(AI.doc_sequence_value,AI.voucher_num)    internal_inv_number
        ,AI.Invoice_type_lookup_code transaction_type
        ,NVL(DECODE( :p_exchange_rate_type, 'User', REPLACE(:p_exchange_rate,',','.')
             , ap_open_bal_rev_rpt_pkg.exch_rate_calc( AI.invoice_currency_code ) ),0) exchange_rate
        ,DECODE(AI.Invoice_type_lookup_code,'PREPAYMENT'
                     ,-1*(NVL(SUM(NVL(XdL.unrounded_entered_cr,0))-SUM(NVL(XdL.unrounded_entered_dr,0)),0))
                     ,NVL(SUM(NVL(XdL.unrounded_entered_cr,0))-SUM(NVL(XdL.unrounded_entered_dr,0)),0))     invoice_amt_entered
        ,DECODE(AI.Invoice_type_lookup_code,'PREPAYMENT'
                     ,-1*(NVL(SUM(NVL(XdL.unrounded_accounted_cr,0))-SUM(NVL(XdL.unrounded_accounted_dr,0)),0))
                     ,NVL(SUM(NVL(XdL.unrounded_accounted_cr,0))-SUM(NVL(XdL.unrounded_accounted_dr,0)),0))  invoice_amt_accounted
FROM
        ap_invoices                 AI
        ,ap_invoice_distributions     AID
        ,hr_operating_units         HOU    
        ,ap_suppliers                 AS1
        ,xla_distribution_links     XDL
        ,xla_ae_lines                 XAL
        ,gl_import_references         GIR
        ,gl_je_headers                GJH
        ,gl_code_combinations         GCC
WHERE
        AS1.vendor_id                =AI.vendor_id
AND     AID.invoice_id                =AI.invoice_id
AND     AI.payment_status_flag      <>'Y'  --bug7581755
AND     HOU.organization_id         =AI.org_id
AND     XDL.event_id                =AID.accounting_event_id
AND     XDL.source_distribution_id_num_1 = AID.invoice_distribution_id
AND     XDL.application_id            =200
--AND     XDL.rounding_class_code = 'LIABILITY'
AND     XDL.rounding_class_code   = DECODE(ai.Invoice_type_lookup_code ,'PREPAYMENT', 'PREPAID_EXPENSE','LIABILITY')
AND     XAL.ae_header_id            =XDL.ae_header_id
AND     XAL.ae_line_num                =XDL.ae_line_num
AND     XAL.ledger_id               =AI.set_of_books_id
AND     XAL.application_id            =200
--AND     XAL.accounting_class_code   ='LIABILITY'
AND     GCC.code_combination_id        =XAL.code_combination_id
AND     GIR.gl_sl_link_id            =XAL.gl_sl_link_id
AND     GIR.gl_sl_link_table        =XAL.gl_sl_link_table
AND     GJH.je_header_id            =GIR.je_header_id
AND     GJH.status                    ='P'
AND     GJH.ledger_id                       = 2161
AND     XAL.ACCOUNTING_DATE            <= :P_AS_OF_DATE
AND ai.org_id=:p_org_id
AND ai.invoice_currency_code = :P_CURRENCY
 AND ai.invoice_currency_code <> :gc_func_currency
 AND 1 = 1
GROUP BY
        HOU.name
        ,fnd_flex_xml_publisher_apis.process_kff_combination_1('FLEX_SELECT_ALL', 'SQLGL', 'GL#', gcc.CHART_OF_ACCOUNTS_ID, NULL, gcc.CODE_COMBINATION_ID, 'ALL', 'Y', 'VALUE')            
        ,AI.invoice_currency_code      
        ,AS1.vendor_name               
        ,AI.invoice_id              
        ,AI.invoice_num                
        ,AI.invoice_date
        ,AI.Invoice_type_lookup_code        
        ,NVL(AI.doc_sequence_value,AI.voucher_num)
        ,AI.exchange_rate        
        ,DECODE( :p_exchange_rate_type, 'User', REPLACE(:p_exchange_rate,',','.')
             , ap_open_bal_rev_rpt_pkg.exch_rate_calc( AI.invoice_currency_code ) )
ORDER BY 1,2,3,5
View Code

3,檢視錶空間使用率

檢視錶空間使用率的sql語句:

ORA-01652 無法透過128 (在表空間 TEMP中)擴充套件temp段
select *
  from (
        
        Select a.tablespace_name,
                
                to_char(a.bytes / 1024 / 1024, '99,999.999') total_bytes,
                
                to_char(b.bytes / 1024 / 1024, '99,999.999') free_bytes,
                
                to_char(a.bytes / 1024 / 1024 - b.bytes / 1024 / 1024,
                        '99,999.999') use_bytes,
                
                to_char((1 - b.bytes / a.bytes) * 100, '99.99') || '%' use
        
          from (select tablespace_name,
                        
                        sum(bytes) bytes
                 
                   from dba_data_files
                 
                  group by tablespace_name) a,
                
                (select tablespace_name,
                        
                        sum(bytes) bytes
                 
                   from dba_free_space
                 
                  group by tablespace_name) b
        
         where a.tablespace_name = b.tablespace_name
        
        union all
        
        select c.tablespace_name,
                
                to_char(c.bytes / 1024 / 1024, '99,999.999') total_bytes,
                
                to_char((c.bytes - d.bytes_used) / 1024 / 1024, '99,999.999') free_bytes,
                
                to_char(d.bytes_used / 1024 / 1024, '99,999.999') use_bytes,
                
                to_char(d.bytes_used * 100 / c.bytes, '99.99') || '%' use
        
          from (select tablespace_name, sum(bytes) bytes
                 
                   from dba_temp_files
                  group by tablespace_name) c,
                
                (select tablespace_name, sum(bytes_cached) bytes_used
                 
                   from v$temp_extent_pool
                  group by tablespace_name) d
        
         where c.tablespace_name = d.tablespace_name
        
        )

 order by tablespace_name
View Code

4、問題很奇怪,臨時表空間使用率較低,初步判斷應該是資源太集中執行導致臨時空間太滿了

5、檢視普通資料檔案是否擴充套件

select d.file_name, d.tablespace_name, d.autoextensible
from dba_data_files d

6、檢視臨時表空間是否可以擴充套件:

select d.file_name,d.tablespace_name,d.autoextensible from dba_temp_files d;

7,增加資料檔案解決問題

問了同事,寫這個sql語句的小夥伴已經離職半年了,所以無人懂這個複雜的sql的業務邏輯了,暫時最佳化sql的建議是無法去做了。採用另外一種發難,直接新增一個新的臨時表空間的資料檔案,設定大一些,設定成4g:

-- 執行新增臨時表空間的資料檔案命令:

ALTERTABLESPACE TEMP

 ADDTEMPFILE'/home/oradata/powerdes/temp05.dbf'                                                                    

 SIZE4G

 AUTOEXTENDON

 NEXT128M;

6,臨時表空間相關

檢視使用消耗臨時表空間資源比較多的sql語句:

        
        
SELECT se.username,
       
       se.sid,
       
       su.extents,
       
       su.blocks * to_number(rtrim(p.value)) asSpace,
       
       tablespace,
       
       segtype,
       
       sql_text

  FROM v$sort_usage su, v$parameter p, v$session se, v$sql s

 WHERE p.name = 'db_block_size'
      
   AND su.session_addr = se.saddr
      
   AND s.hash_value = su.sqlhash
      
   AND s.address = su.sqladdr

 ORDER BY se.username, se.sid;

增加資料檔案

當臨時表空間太小時,就需要擴充套件臨時表空間(新增資料檔案、增大資料檔案、設定檔案自動擴充套件);有時候需要將臨時資料檔案分佈到不同的磁碟分割槽中,提升IO效能,也需要透過刪除、增加臨時表空間資料檔案。

ALTERTABLESPACE TEMP

 ADDTEMPFILE'/home/oradata/powerdes/temp05.dbf'

 SIZE4G

 AUTOEXTENDON

 NEXT128M;

刪除資料檔案

例如,我想刪除臨時表空間下的某個檔案,那麼我們有兩種方式刪除臨時表空間的資料檔案。

方法1:

SQL> altertablespace temp droptempfile'/home/oradata/powerdes/temp03.dbf' ;

Tablespace altered.

SQL>

# 這個方法會刪除物理檔案

[oracle@pldb1 ~]$ ll /home/oradata/powerdes/temp03.dbf

ls: cannot access /home/oradata/powerdes/temp03.dbf: No such file or directory

[oracle@pldb1 ~]$

方法2:

SQL> alterdatabasetempfile'/home/oradata/powerdes/temp04.dbf'dropincludingdatafiles;

Database altered.

SQL>

注意:刪除臨時表空間的臨時資料檔案時,不需要指定INCLUDING DATAFILES 選項也會真正刪除物理檔案,否則需要手工刪除物理檔案。

調整檔案大小

如下例子,需要將臨時資料檔案從128M大小調整為256M

SQL> alterdatabasetempfile'/home/oradata/powerdes/temp02.dbf'resize256M;

Database altered.

SQL>

檔案離線聯機

-- 離線

alterdatabasetempfile'/home/oradata/powerdes/temp02.dbf'offline;

-- 聯機

alterdatabasetempfile'/home/oradata/powerdes/temp02.dbf'online;

收縮臨時表空間

排序等操作使用的臨時段,使用完成後會被標記為空閒,表示可以重用,佔用的空間不會立即釋放,有時候臨時表空間會變得非常大,此時可以透過收縮臨時表空間來釋放沒有使用的空間。收縮臨時表空間是ORACLE 11g新增的功能。

SQL> ALTERTABLESPACE TEMP SHRINKSPACEKEEP8G;

SQL> ALTERTABLESPACE TEMP SHRINKTEMPFILE'/home/oradata/powerdes/temp05.dbf'

相關文章