#oracle
Грузим большие объемы (порядка 500 тыс. записей) каждые 5 минут с помощью sqlldr в секционированную таблицу. Секции по часам, плюс есть еще подсекции (12 штук). Контрол файл: OPTIONS (DIRECT=TRUE, ERRORS=500000) UNRECOVERABLE load data infile '{FILENAME}' append into table TBL_NAME fields terminated by '|' TRAILING NULLCOLS ( ) Иногда возникает deadlock. При этом обнаружили непонятную проблему. Ожидаем, что при возникновении ошибки Oracle должен выполнить rollback всех загруженных строк. Но проверка данных в целевой таблице показала, что данные не откатились, а были загружены. Как такое можно объяснить? По окончании загрузки в лог файле видим: SQL*Loader-925: Error while uldlgs: OCIStmtExecute (ptc_hp) ORA-00060: deadlock detected while waiting for resource SQL*Loader-2026: the load was aborted because SQL Loader cannot continue. Table TBL_NAME: 0 Rows successfully loaded. 0 Rows not loaded due to data errors. 0 Rows not loaded because all WHEN clauses were failed. 0 Rows not loaded because all fields were null. Date conversion cache disabled due to overflow (default size: 1000)
Ответы
Ответ 1
Нет, отката (rollback), в привычном понимании этого термина, с установленой опцией direct=true SQL*Loader не производит. Direct path load не пишет, ни UNDO, ни (по умолчанию) redo logs. Загружаемые данные подготавливаются в буфере и пишутся напрямую в datafile, используя не отформатированные блоки поверх HWM (high-water-mark). При возникновении ошибки (errors=0) или, если порог допостимых ошибок превышен (errors>0), SQL*Loader прерывает загрузку, но все уже загруженые страницы сохранятся. Подробнее о прерывании загрузки в секции Interrupted Loads. Воиспроводимый пример для наглядности. Попробуем записать null в колонку с ограничением not null: create table stage (id number, item varchar (32), created date) partition by range (created) interval (numToDsInterval (1, 'day')) ( partition stage_p1 values less than (date'2018-06-21') ) ; Генеририруем 100 строчек данных с null в 66 строке: insert into stage select rownum, case when rownum<>66 then 'item '||rownum end, date'2018-06-20'+rownum/24 from xmltable ('1 to 100'); $ sqlplus -l -s user/pass@localhost/db1 <
Комментариев нет:
Отправить комментарий