Массовые задания Oracle, как предотвратить блокировки - PullRequest
2 голосов
/ 24 января 2012

У нас есть несколько ночных заданий, работающих в экземпляре Oracle 11g R2, но не все эти задания находятся под нашим контролем. Некоторые из них - внешние загрузки данных, выполняемые третьими сторонами. Задания реализованы в виде пакетов PL / SQL и выполняются с использованием DBMS_SCHEDULER средств.

Некоторые из этих заданий работают с одним и тем же набором данных, таблицей с записями пользователей, e. г. обновление личных данных, удаление пользователей, вышедших на пенсию, добавление новых пользователей. Поскольку в заданиях в основном используются массовые операторы для запуска обновлений, мы уже несколько раз сталкивались с блокирующими блокировками, чтобы убить отдельные задания, чтобы другие могли их выполнить.

Как можно предотвратить столкновение заданий друг с другом?

Я думаю о таких вещах, как:

  • настройка мета-задания, которое знает о зависимостях и координирует зависимые задания
  • создание расписаний, которые держат конфликтующие задания как можно более раздельно
  • координация заданий с третьими сторонами для предотвращения конфликтов между "внешними" и "внутренними" заданиями
  • не использует массовые операторы (обновляя все сразу с помощью одного MERGE или UPDATE), но вместо этого обновляет по одному, передавая промежуточные результаты

Особенно последний вариант кажется мне правдоподобным, чтобы уменьшить вероятность блокировки блокировок. Но я знаю, что производительность сильно страдает, когда я переключаю наши задания с массовых обновлений на циклические по курсорам.

Ответы [ 3 ]

4 голосов
/ 24 января 2012

Это может быть хорошим использованием пакета DBMS_LOCK.DBMS_LOCK позволяет вам получить доступ к той же модели постановки / блокировки, которая используется Oracle для внутреннего использования.

Вы можете установить постановку в очередь, и тогда несколько процессов могут принять эту постановку в очередь в различных режимах блокировки.Блокировки будут отображаться, как и любая другая очередь, с типом «UL» (для блокировки пользователя).

Например, предположим, что у вас есть три процесса, которые могут работать одновременно, но затем у вас есть процесс, который должен ждатьдля всех трех из этих процессов, которые должны быть запущены сами по себе, а затем следуют еще два процесса, которые могут запускаться одновременно после завершения этого процесса.

Первые три процесса могут получить очередь UL.в режиме 'S' (общий), и все они смогут работать одновременно.Затем запустите процесс, который должен быть запущен сам по себе, но в начале кода сделайте так, чтобы он принял очередь UL в режиме «X» (эксклюзив).Этот процесс будет ожидать завершения трех процессов, содержащих очередь в режиме совместного использования.Теперь вы также можете запустить два последних процесса снова в режиме совместного использования.Они будут стоять в очереди за процессом, который запрашивает эксклюзивные блокировки режима, и все работает в нужном вам порядке.

Это простой пример.С более чем одной блокировкой типа UL и несколькими режимами, в которых можно удерживать блокировки, ваши процессы и стратегия блокировки могут быть произвольно сложными.

Надеюсь, это поможет.

0 голосов
/ 24 января 2012

Меньшие транзакции уменьшают вероятность столкновения, однако Мерфи может / ударит вас в любом случае. Я бы начал работу в «правильном» порядке ...

0 голосов
/ 24 января 2012

Очень сложно давать какие-либо советы, не зная всех деталей.

Самое простое - планировать задания, чтобы они не перекрывались (если позволяет процесс).

Если вы не можете этого сделать, то, вероятно, нет простого решения, особенно если есть задания, которые вы не можете изменить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...