ORA-01652 - 无法在表空间中将临时段扩展 4096 (oracle 10)

Posted

技术标签:

【中文标题】ORA-01652 - 无法在表空间中将临时段扩展 4096 (oracle 10)【英文标题】:ORA-01652 - unable to extend temp segment by 4096 in tablespace (oracle 10) 【发布时间】:2015-05-15 03:44:01 【问题描述】:

问题:

我是 Oracle 新手,我认为我缺少一些导致我的临时表空间被填满的基本知识。

我正在打开与我的数据库的连接并多次运行 pl/sql 过程以插入行。每次我运行该过程时,我的 TEMP 表空间中的空闲块数都会减少。当空闲块的数量太少时,该过程将失败并出现错误“ORA-01652 - 无法在表空间中将临时段扩展 4096”。如果我关闭数据库连接,TEMP 表空间中的空闲块将重置为块的总数,我可以继续重新运行该过程。如何在不必关闭和打开数据库的情况下释放 TEMP 表空间块?我以为我需要添加一个提交语句,但这没有帮助。

谢谢


代码:

查询以检查 free_MB(每次运行该过程都会减少)。

SELECT tablespace_name,
total_blocks,
used_blocks,
free_blocks,
total_blocks*16/1024 as total_MB,
used_blocks*16/1024 as used_MB,
free_blocks*16/1024 as free_MB
FROM v$sort_segment; 

我多次运行 SQL,直到 free_mb 减少到 0 并出现错误:

DECLARE
  p_samples LOG_ENTRY_ARRAY;
  longSample clob;
BEGIN
  For v_COUNTER IN 1..32767 LOOP
    longSample := longSample || 'a';
  END loop;
  -- initialize the input
  p_samples := LOG_ENTRY_ARRAY(longSample, 'short sample');
  for i in 1..100 LOOP
    INSERT_SUMMARY_SAMPLES('TABLE1', 1000, 1, 2, p_samples);
  END loop;
  commit;
END;

被调用的过程将一堆插入到两个表中:

create or replace 
PROCEDURE INSERT_SUMMARY_SAMPLES 
(
  p_TABLE_NAME IN VARCHAR2  
, p_TS IN NUMBER  
, p_SIGNATURE_ID IN NUMBER  
, p_COUNT IN NUMBER  
, p_SAMPLES IN LOG_ENTRY_ARRAY  
) AS 
  tbl_summary varchar2(30);
  tbl_samples varchar2(30);
  summary_id number(10,0);
  sample varchar2(32767);
BEGIN      
  tbl_summary := 'TBL_' || p_TABLE_NAME || '_SUMMARIES';
  tbl_samples := 'TBL_' || p_TABLE_NAME || '_SAMPLES';

  -- insert summary and get the id
  EXECUTE IMMEDIATE 'INSERT INTO ' || tbl_summary 
    || ' (agg_start_ts, signature_id, count, num_samples) VALUES (:a,:b,:c,:d) returning id into :1' 
    using p_ts, p_signature_id, p_count, p_SAMPLES.count returning into summary_id;
  dbms_output.put_line('new summary_id is : ' || summary_id);
  -- insert samples
  FOR i in 1..p_SAMPLES.count LOOP
    -- convert clob to varchar2
    CLOB_TO_VARCHAR(p_SAMPLES(i),sample);
    EXECUTE IMMEDIATE 'INSERT INTO ' || tbl_samples || ' (summary_id, log_entry) VALUES (:a,:b)' using summary_id, sample;
    -- dbms_output.put_line('insert sample : ' || TO_CHAR(p_SAMPLES(i)));
  END LOOP;  
END INSERT_SUMMARY_SAMPLES;

CLOB_TO_VARCHAR 是另一个过程:

create or replace 
PROCEDURE CLOB_TO_VARCHAR (
  p_clob IN CLOB,
  p_varchar OUT VARCHAR2
  )
AS
  v_output varchar2(32767);
  l_amount BINARY_INTEGER := 32767;
  l_pos INTEGER := 1;
  l_clob_len INTEGER := 0;
BEGIN
  l_clob_len := DBMS_LOB.getlength (p_clob);
  WHILE l_pos < l_clob_len
  LOOP
    dbms_lob.READ(p_clob, l_amount, l_pos, v_output);
    l_pos := l_pos + l_amount;
  END LOOP;
  p_varchar := v_output;
END CLOB_TO_VARCHAR;

【问题讨论】:

你有没有想过这个问题?听起来我遇到了非常相似的情况,我想知道你发现了什么 【参考方案1】:

您的 TEMP 表空间正在快速填满。您可能需要手动增加表空间。 ORA-01652 Unable to extend temp segment by in tablespace 和

的可能重复项

ORA-01652: unable to extend temp segment by 128 in tablespace SYSTEM: How to extend?

【讨论】:

为什么在我对过程的调用完成后没有释放临时空间?看起来只有在我关闭与数据库的连接时才会释放临时空间。我调用该过程的应用程序使用 c3p0 连接池,我认为它实际上从未关闭连接。如果长时间运行的连接池会导致内存用完,如何使用? 我认为只有在关闭连接后才释放临时空间在逻辑上是正确的。 Reg使用长时间运行的连接池,你的意思是如何避免临时表空间的内存中断。如果是这样,我的建议是尽可能使用短事务(频繁提交),因为它们可能会释放临时空间。我希望通过使用 ALTER TABLESPACE temp ADD TEMPFILE 添加更多空间(数据文件)来增加表空间 在我的测试中,运行提交不会释放临时空间。只有关闭连接。我做了更多分析,看起来 LOB 使用了临时空间。我想我需要找出连接会话结束之前 CLOB 使用空间的原因。【参考方案2】:

我猜你在某个地方有一个临时 lob,但它没有被明确释放。 LOG_ENTRY_ARRAY 定义在哪里?

【讨论】:

以上是关于ORA-01652 - 无法在表空间中将临时段扩展 4096 (oracle 10)的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01652: 无法在表空间 TEMP 中将临时段扩展 128 - 这是可恢复的吗?

Pentaho Spoon 转换抛出:ORA-01652:无法在表空间 TEMP 中将临时段扩展 128

ORA-01652: 使用 DBMS_RANDOM.VALUE 时无法在表空间 TEMP 错误中将临时段扩展 128

无法在表空间 PSTEMP 中将临时段扩展 16

sql 如何解决Oracle“ORA-01652:无法在表空间X中用N扩展临时段”

无法在表空间 TEMP 数据库驱动程序错误中将临时段扩展 128 [关闭]