Почему ведение журнала ошибок dml игнорируется в параллельном операторе

#oracle #error-handling #parallel-processing

#Oracle #обработка ошибок #параллельная обработка

Вопрос:

У меня есть insert-select оператор, который я выполняю параллельно.

Я пытаюсь добавить dml error logging для захвата исключений.

Но когда я изменяю сеанс для использования parallel, ведение журнала ошибок просто игнорируется.

 -- This is my error table:
TRUNCATE TABLE DWH.ERR$_DWH_CONV;

-- This code is finish with no error and insert rows to DWH.ERR$_DWH_CONV
BEGIN
EXECUTE IMMEDIATE
'alter session enable parallel dml';

INSERT
        /*  monitor parallel(1) */
INTO    DWH.PURCHASE
select *
FROM    DWH.PURCHASE_C LOG ERRORS
INTO    DWH.ERR$_DWH_CONV ('DWH.PURCHASE') REJECT LIMIT UNLIMITED ;

commit;
END;
  

Но когда я запускаю этот код (parallel 6) — возникает исключение (ORA-12801)
и в таблице ошибок нет никаких изменений:

 BEGIN
EXECUTE IMMEDIATE
'alter session enable parallel dml';
INSERT
        /*  monitor parallel(6) */
INTO    DWH.PURCHASE
select *
FROM    DWH.PURCHASE_C LOG ERRORS
INTO    DWH.ERR$_DWH_CONV ('DWH.PURCHASE') REJECT LIMIT UNLIMITED ;
commit;
END;
  

Это различие также появляется, если я включаю или отключаю alter-session .

Я использую Oracle 11g.

Согласно документам Oracle, я не видел никаких ограничений на использование dml error logging with parallel ..

Комментарии:

1. ORA-12801 это общее сообщение об ошибке, которое указывает, когда один из нескольких потоков завершает работу. Это может помочь захватить весь стек ошибок и опубликовать его здесь. Есть некоторые ошибки, которые не приводят к ведению журнала, такие как ORA-00600 .

2. Моя ошибка, конкретная ошибка заключалась в нарушении ограничения PK

Ответ №1:

Согласно документации для error_logging_clause

Ограничения на ведение журнала ошибок DML

  • Следующие условия приводят к сбою инструкции и откату без вызова возможности ведения журнала ошибок:

    • Любая операция ВСТАВКИ или слияния по прямому пути, которая вызывает ограничение уникальности или нарушение индекса.

Параллельный DML использует запись по прямому пути по умолчанию, но вы можете отключить прямой путь с помощью подсказки NOAPPEND . Это позволит оператору использовать параллелизм, но при обычной записи. Это не так быстро, как параллельная запись по прямому пути, но, по крайней мере, лучше, чем обычная однопоточная запись.

Комментарии:

1. Спасибо за ваш ответ. Я просто не понял. У меня не было подсказки append, единственное изменение связано с parallel… почему оптимизатор выберет вставку прямого пути, когда включена функция parallel?

2. @user2671057 Запись по прямому пути выполняется по умолчанию при использовании параллельного DML. Я внес небольшое обновление в свой ответ.

3. Теперь это имеет смысл. Спасибо!