Как разрешить моему администратору БД приостановить и возобновить хранимую процедуру, которая обновляет каждую строку в большой таблице? - PullRequest
4 голосов
/ 30 октября 2008

У меня есть таблица из примерно миллиона строк, и мне нужно обновить каждую строку в таблице с результатом длинного вычисления (вычисление получает потенциально различный результат для каждой строки). Поскольку это занимает много времени, администратор базы данных должен иметь возможность контролировать выполнение. Этот конкретный расчет должен выполняться один раз в год (он делает итоги на конец года). Я хотел создать задание, используя DBMS_SCHEDULER.CREATE_JOB, которое получит 100 строк из таблицы, обновит их и затем остановит; при следующем выполнении задания будет выбрано место, где было прервано предыдущее выполнение.

Моей первой мыслью было включить этот код в конец моей хранимой процедуры:

-- update 100 rows, storing the primary key of the last
-- updated row in last_id
-- make a new job that will run in about a minute and will
-- start from the primary key value just after last_id
dbms_scheduler.create_job
( job_name=>'yearly_summary'
, job_type=>'STORED_PROCEDURE'
, job_action=>'yearly_summary_proc(' || last_id || ')'
, start_date=>CURRENT_TIMESTAMP + 1/24/60
, enabled=>TRUE
);

Но я получаю эту ошибку при запуске хранимой процедуры:

ORA-27486: insufficient privileges
ORA-06512: at "SYS.DBMS_ISCHED", line 99
ORA-06512: at "SYS.DBMS_SCHEDULER", line 262
ORA-06512: at "JBUI.YEARLY_SUMMARY_PROC", line 37
ORA-06512: at line 1

Предложения о других способах сделать это приветствуются. Я бы предпочел использовать DBMS_SCHEDULER, и я бы предпочел не создавать никаких таблиц; поэтому я передаю last_id хранимой процедуре.

Ответы [ 3 ]

7 голосов
/ 30 октября 2008

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

Не создавая никаких новых объектов, вы можете использовать пакет DBMS_ALERT , чтобы ваш администратор БД мог отправить предупреждение, которое приостанавливает работу. Ваш код может вызывать метод DBMS_ALERT.WAITONE через каждые сто строк, чтобы проверить, сигнализировал ли администратор баз данных конкретное предупреждение (то есть предупреждение PAUSE_YEAREND_JOB). Если предупреждение не получено, код может продолжаться. Если получено предупреждение, вы можете приостановить код либо до получения другого предупреждения (например, RESUME_YEAREND_JOB), либо через фиксированный период времени, либо на основании сообщения, отправленного администратором базы данных с предупреждением PAUSE_YEAREND_JOB (т.е. сообщение может быть количество секунд для паузы или дата для паузы до и т. д.)

Конечно, вы можете сделать то же самое, создав новую таблицу, попросив администратора базы данных записать в таблицу строку, чтобы приостановить работу, и считывая из таблицы каждые N строк.

2 голосов
/ 31 октября 2008

В дополнение к ответу о DBMS_ALERT ваш администратор БД будет благодарен за возможность увидеть, где находится ваша хранимая процедура. Для этого вы должны использовать функциональность DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS в Oracle.

2 голосов
/ 30 октября 2008

Еще один путь для изучения - инструменты поддержки планировщика dbms для окон выполнения и планов ресурсов.

http://www.oracle -base.com / статьи / 10г / Scheduler10g.php

, а также:

http://download -west.oracle.com / Docs / кд / B19306_01 / server.102 / b14231 / schedover.htm # sthref3501

С помощью окон и планов ресурсов ваш администратор базы данных может просто настроить систему для выполнения вашей процедуры в соответствии с определенными правилами, включая окно задания и выполнение с использованием только определенного количества ресурсов (т. Е. Использования ЦП).

Таким образом, процедура может выполняться один раз в год, а использование процессора может контролироваться.

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

Другой идеей было бы написать вашу процедуру для обработки всех записей, но фиксировать каждую 1000 или около того. Команда dbms job.cancel () может быть использована вашим администратором базы данных для отмены задания, если они хотят, чтобы оно было остановлено, и затем они могут возобновить его (перепланировав или повторно запустив), когда они будут готовы к работе. Хитрость заключается в том, что процедура должна иметь возможность отслеживать обработанные строки, например, с использованием столбца «process_date» или отдельной таблицы, в которой перечислены первичные ключи и дата обработки.

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