ORA-30036: невозможно расширить сегмент на 8 в табличном пространстве отмены «UNDOTBS»

Я запускаю задание cron, которое имеет следующий блок PL/SQL:

declare  
  begin  
--insert into DB_LOGS_TEMP table from DB_LOGS table  
INSERT INTO DB_LOGS_TEMP SELECT * FROM DB_LOGS WHERE DB_LOG_ID NOT IN(SELECT DB_LOG_ID from DB_LOGS_TEMP );  
--keep the lat 10 records and delete other records  
DELETE DB_LOGS where rowid  in (  
select rid from (  
select t.rowid rid,  
       row_number() over(partition by T.DB_LOG_ID order by T.TIMESTAMP desc) as rn  
from DB_LOGS t)  
where rn > 10);  
end;  

В таблице DB_LOGS 10247302 строки. При запуске задания cron выдает ошибку ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS'. Является ли увеличение количества таблиц единственным решением этой проблемы и как это сделать? UNDOTBS имеет 524288000 байт.


person Andrew    schedule 27.07.2016    source источник
comment
Вы, вероятно, удаляете множество записей без фиксации. Возможно, вам следует чаще перебирать таблицу, выдавая коммиты. Вы можете это сделать или это должно быть в той же транзакции?   -  person vercelli    schedule 27.07.2016


Ответы (2)


У меня это работает при увеличении табличного пространства и включении автоматического расширения.

 ALTER DATABASE DATAFILE '/vg01lv11/oracle//data/undotbs_d1_O2P00R11.dbf' AUTOEXTEND ON MAXSIZE 10g;

ALTER DATABASE DATAFILE '/vg01lv11/oracle//data/undotbs_d1_O2P00R11.dbf'
       RESIZE 1000M;
person Andrew    schedule 27.07.2016
comment
Будь осторожен; вы также можете установить maxsize, чтобы Oracle не заполнял вашу файловую систему. Чтобы файл данных не превышал 10 г, вы можете сказать: ALTER DATABASE DATAFILE '/vg01lv11/oracle//data/undotbs_d1_O2P00R11.dbf' AUTOEXTEND ON MAXSIZE 10g; - person Mark Stewart; 27.07.2016
comment
я сделаю это изменение @Mark - person Andrew; 27.07.2016

Если вы можете позволить себе удаление в разных транзакциях:

DECLARE
  i PLS_INTEGER;
BEGIN
  --insert into DB_LOGS_TEMP table from DB_LOGS table
  INSERT INTO DB_LOGS_TEMP
  SELECT *
  FROM DB_LOGS
  WHERE DB_LOG_ID NOT IN
    (SELECT DB_LOG_ID FROM DB_LOGS_TEMP
    );
  COMMIT;
  i:=50;
  --keep the lat 10 records and delete other records
  WHILE i>=10
  LOOP
    DELETE DB_LOGS
    WHERE rowid IN
      (SELECT rid
      FROM
        (SELECT t.rowid rid,
          row_number() over(partition BY T.DB_LOG_ID order by T.TIMESTAMP DESC) AS rn
        FROM DB_LOGS t
        )
      WHERE rn > i
      );
    COMMIT;
    i:=i-5;
  END LOOP;
END;
person vercelli    schedule 27.07.2016
comment
у меня это работает при увеличении табличного пространства и включении автоматического расширения. Я не думаю, что транзакция была реальной проблемой. - person Andrew; 27.07.2016
comment
@ Эндрю, да, твой UNDO TBS был очень маленьким. Но будьте осторожны с этими огромными удалениями, они могут увеличить ваш UNDO. - person vercelli; 27.07.2016