CftClub.ru
Клуб специалистов ЦФТ-Банк

Выполнение заданий по расписанию.
На страницу 1, 2  След.
 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Уроки ЦФТ-Банк для начинающих
Предыдущая тема :: Следующая тема  
Автор Сообщение
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеПн Июн 01, 2015 19:57   Выполнение заданий по расписанию. Ответить с цитатой
Полезность: Нет оценки
Добрый день, коллеги.
Впервые столкнулся с ситуацией, когда задание сконфигурировано на запуск в 5 утра, а реальное время запуска в 13-30...
Причем само задание уже пару месяцев работает, запускается все время в 5...
Может быть кто нибудь сталкивался с аналогичной ситуацией...

Запущено 28/05/2015 05:00:03. Выполнено 28/05/2015 05:00:04.
Запущено 29/05/2015 05:00:03. Выполнено 29/05/2015 05:00:03.
Запущено 30/05/2015 05:00:03. Выполнено 30/05/2015 05:00:03.
Запущено 31/05/2015 13:30:53. Выполнено 31/05/2015 14:52:08.
Запущено 01/06/2015 05:00:00. Выполнено 01/06/2015 05:00:00.
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеВт Июн 02, 2015 07:04   Re: Выполнение заданий по расписанию. Ответить с цитатой
Полезность: 1
Матвеев Евгений пишет:

Впервые столкнулся с ситуацией, когда задание сконфигурировано на запуск в 5 утра, а реальное время запуска в 13-30...
...
Может быть кто нибудь сталкивался с аналогичной ситуацией...

Оракловый механизм джоб (job) запускает задание (джобу) с какой-то погрешностью во времени. Запуск в 5ч означает - не ранее 5:00 (обычно, на 1-10-30 минут позже - в зависимости от нагруженности сервера в этот момент).
Есть процесс-'координатор', который с определенной периодичностью проверяет - не нужно ли запустить очередную джобу.
Вот этот процесс-координатор если остановлен на сервере - никакие джобы запущены не будут.
Есть ограничение (настройка оракл-сервера) на количество одновременно запущенных джоб (скажем, на более 5). Тогда очередная джоба будет запущена только по завершении выполняющейся.
ДБА-админы иногда специально запрещают запуск джоб (останавливают процесс-координатор).
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеВт Июн 02, 2015 08:01   Re: Выполнение заданий по расписанию. Ответить с цитатой
Полезность: 1
Damir пишет:
Матвеев Евгений пишет:

Впервые столкнулся с ситуацией, когда задание сконфигурировано на запуск в 5 утра, а реальное время запуска в 13-30...
...
Может быть кто нибудь сталкивался с аналогичной ситуацией...

Оракловый механизм джоб (job) запускает задание (джобу) с какой-то погрешностью во времени. Запуск в 5ч означает - не ранее 5:00 (обычно, на 1-10-30 минут позже - в зависимости от нагруженности сервера в этот момент).
Есть процесс-'координатор', который с определенной периодичностью проверяет - не нужно ли запустить очередную джобу.
Вот этот процесс-координатор если остановлен на сервере - никакие джобы запущены не будут.
ДБА-админы иногда специально запрещают запуск джоб (останавливают процесс-координатор).
Не обязательно проблема в координаторе.

Damir пишет:
Есть ограничение (настройка оракл-сервера) на количество одновременно запущенных джоб (скажем, на более 5). Тогда очередная джоба будет запущена только по завершении выполняющейся.
Вот именно.
Если количество джобов в очереди, которые нужно выполнить, превышает количество заданий, которые одновременно могут быть запущены, то, несмотря на то, что время для запуска настало, "лишние" джобы не могут быть стартованы до тех пор, пока для них не освободится место.
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВт Авг 04, 2015 11:00    Ответить с цитатой
Полезность: Нет оценки
... и еще вопрос ...может кто сталкивался...
Как сохранять pipe или иные сообщения при выполнения заданий по расписанию ?
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеВт Авг 04, 2015 11:37    Ответить с цитатой
Полезность: 1
Матвеев Евгений пишет:
... и еще вопрос ...может кто сталкивался...
Как сохранять pipe или иные сообщения при выполнения заданий по расписанию ?

Можешь вычитать пайп самостоятельно и сохранить куда считаешь нужным.
nobel
Профи


Вступление в Клуб: 28.09.2011
СообщениеВт Авг 04, 2015 15:02    Ответить с цитатой
Полезность: 1
чтобы сохранить на сервере логи выполнения задания по расписанию необходимо необходимо создать программно файл на сервере,заполняем файл и потом закрываем.

например так
Код:

--открываем файл
file:=stdio.open(::[SYSTEM_PARAMS].[GET]('PATH',null),'check_invalid '||replace(to_char(sysdate,'DD/MM/YYYY'),'/','')||'.txt','w');

--через функцию заполняем лог
procedure write_debug(line varchar2,file integer) is
begin
stdio.put_line(file,line,false,null,stdio.DOSTEXT);
end;

--в конце закрываем
stdio.close(file);


я так делал когда писал свое задание по расписанию по недействительным удостоверениям
prankster
Профи


Вступление в Клуб: 22.08.2014
СообщениеВт Авг 04, 2015 16:05    Ответить с цитатой
Полезность: 1
nobel пишет:
чтобы сохранить на сервере логи выполнения задания по расписанию необходимо необходимо создать программно файл на сервере,заполняем файл и потом закрываем.

например так
Код:

--открываем файл
file:=stdio.open(::[SYSTEM_PARAMS].[GET]('PATH',null),'check_invalid '||replace(to_char(sysdate,'DD/MM/YYYY'),'/','')||'.txt','w');

--через функцию заполняем лог
procedure write_debug(line varchar2,file integer) is
begin
stdio.put_line(file,line,false,null,stdio.DOSTEXT);
end;

--в конце закрываем
stdio.close(file);


я так делал когда писал свое задание по расписанию по недействительным удостоверениям


Если задание по расписанию просто выполняет некие действия и пишет лог - так сойдет, а если вызывает другие операции... То придется модифицировать все вызываемые операции, которые пишут в пайп. Либо же вычитывать пайп в главной операции и писать в файл/справочник.
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВт Авг 04, 2015 18:08    Ответить с цитатой
Полезность: Нет оценки
Спасибо коллеги...
По write_debug(line varchar2,file integer) идея понятна, ...
Вычитать пайп... как это сделать? где то можно пример посмотреть?
Ранее не сталкивался...
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеСр Авг 05, 2015 07:14    Ответить с цитатой
Полезность: 1
Матвеев Евгений пишет:
...

ну тут народ насоветовал - каждый свой самокат изобрел.
Если у нас 'платформа' - то пользоваться надо системными функциями.
Системной функцией вывода отладочного сообщения является
rtl.debug()
а вот куда это сообщение будет выводится - зависит от установки потока.
есть константы
rtl.DEBUG2LOG
rtl.DEBUG2PIPE
rtl - пакет оракловый, советую изучить - там на русском комментов куча - народ постарался изложил лучше чем в документации.
Матвеев Евгений пишет:
...

возможно, достаточно будет перенаправить поток сообщений в ЛОГ (а не в Пайп). Тупо поищи по коду в своей системе константы DEBUG2PIPE, DEBUG2LOG

PS: Random-чика что-то не видать, без него народ во все тяжкие пустился Smile
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеСр Авг 05, 2015 09:20    Ответить с цитатой
Полезность: 1
Damir пишет:

PS: Random-чика что-то не видать, без него народ во все тяжкие пустился Smile


Код:

pragma include(::[REPS_DATA].[LIB_EXCEPT]);
&except(TIMED_OUT, -20302);

function read_pipe(p_name varchar2, p_timeout integer := 2) return varchar2 is
v   varchar2(32767);
n   number;
begin
   n := dbms_pipe.receive_message(p_name,p_timeout);
   if n = 0 then
      dbms_pipe.unpack_message(v);
      return v;
   elsif n = 1 then
      &raise_(TIMED_OUT_EXCEPTION, 'Время ожидания вышло');
   elsif n = 3 then
      return null;   --   Прервано пользователем
   elsif n = 2 then
      pragma error('32 кб под буфер недостаточно при чтении данных из пайпы');   --   Record in pipe too big for buffer (should not happen). Надо бросить исключение
   else
      pragma error('При чтении из канала сообщений возник неизвестный код ошибки: '||n);
   end if;

   return null;
end;

procedure write_pipe(p_name varchar2, p_message varchar2) is
v$state   number;
begin
   dbms_pipe.pack_message(p_message);
   v$state := dbms_pipe.send_message(p_name, 300);
end;

procedure ReadPipe(p_info varchar2) is
v$pipe   varchar2(32767);
v$file   varchar2(32767);
v$str   varchar2(32767);
v$count   number;
begin
   v$pipe := upper('debug$'||p_info);
   v$file := './'||v$pipe||'.pipe';
   for   (   select s(s.[osuser]:u, s.[machine]:m, s.[program]:p) in v$session%rowtype where s.[client_info] = p_info ) loop
      v$str := 'Пользователь: '||s.u||nl$||'Машина: '||s.m||nl$||'Программа: '||s.p||nl$||'Время: '||to_char(sysdate,'dd.mm.yyyy hh24:mi:ss');
      ::[REPS_DATA].[LIB_FILE].AppendFileStr(v$file,v$str);
   end loop;

   v$count := 0;
   loop
      utils.sleep(1);
      loop
         begin
            v$str := read_pipe(v$pipe,1);
            ::[REPS_DATA].[LIB_FILE].AppendFileStr(v$file,v$str);
            v$count := 0;
         exception when TIMED_OUT then
            v$count := v$count + 1;
            exit;
         end;
      end loop;

      for   (   select m(1) in v$session%rowtype
            where   lower(m.[PROGRAM]) = 'oramon.exe'
               and m.[ACTION] like '%'||p_info   ) loop
         --   Появилась программа-монитор.
         --   Надо сообщить туда, что пайпа вычитывалась, и завершать команду.
         write_pipe(v$pipe,'mon Внимание! Канал сообщений был прочитан и выложен в файл '||v$file);
         return;
      end loop;

      v$str := null;
      for   (   select s(1) in v$session%rowtype where s.[client_info] = p_info ) loop
         v$str := '1';
      end loop;

      if v$str is null then
         --   сессия не существует, можно выйти
         write_pipe(v$pipe,'sid Внимание! Канал сообщений был прочитан и выложен в файл '||v$file);
         exit;
      end if;

      if v$count >= 5 then
         write_pipe(v$pipe,'5 Внимание! Канал сообщений был прочитан и выложен в файл '||v$file);
         exit;
      end if;
      
   end loop;
end;

procedure PipeMonitor is
begin
   --   Создаем для каждой команду чтения канала
   for   (   select w(s.[client_info] :info
         ) in v$session_wait%rowtype, (v$session%rowtype :s)
         where   lower(w.[event]) like '%pipe%put%'
            and s.[SID] = w.[sid]
            and w.[SECONDS_IN_WAIT] > 5
            and not exists(   select v(1) in v$session%rowtype
                        where   lower(v.[PROGRAM]) = 'oramon.exe'
                           and v.[ACTION] like '%'||s.[CLIENT_INFO]   )

   ) loop
      ReadPipe(w.[info]);
   end loop;
end;


Запускать PipeMonitor.


Последний раз редактировалось: Random (Ср Авг 05, 2015 09:26), всего редактировалось 1 раз
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеСр Авг 05, 2015 09:21    Ответить с цитатой
Полезность: Нет оценки
Спасиб.
Посмотрю.
Вообще хотелось бы, конечно, (ну это в идеале) для каждой своей запускаемой JOB операции сохранять в соответствующей записи справочника с параметрами (а лучше массив структуры) историю системных сообщений запуска...

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

PS: Random-чика что-то не видать, без него народ во все тяжкие пустился Smile
У Вас тут мафия своя...))) COSA NOSTRA от CFTCLUB
prankster
Профи


Вступление в Клуб: 22.08.2014
СообщениеСр Авг 05, 2015 09:31    Ответить с цитатой
Полезность: 1
Матвеев Евгений пишет:
Спасиб.
Посмотрю.
Вообще хотелось бы, конечно, (ну это в идеале) для каждой своей запускаемой JOB операции сохранять в соответствующей записи справочника с параметрами (а лучше массив структуры) историю системных сообщений запуска...

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

PS: Random-чика что-то не видать, без него народ во все тяжкие пустился Smile
У Вас тут мафия своя...))) COSA NOSTRA от CFTCLUB


Ну так не проблема же, сделать справочник, в котором класс операции, имя операции и массив истории запуска. В массиве дата и время запуска, лог исполнения (главное не переполнять), запустивший пользователь, опционально - еще колонка для параметров запуска операции. Ну и в автономной транзакции (на случай аварийного завершения при отсутствии обработчика, главное без ссылок на создаваемые объекты) писать туда инфо при каждом запуске.
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеСр Авг 05, 2015 09:43    Ответить с цитатой
Полезность: Нет оценки
prankster пишет:
Матвеев Евгений пишет:
Спасиб.
Посмотрю.
Вообще хотелось бы, конечно, (ну это в идеале) для каждой своей запускаемой JOB операции сохранять в соответствующей записи справочника с параметрами (а лучше массив структуры) историю системных сообщений запуска...

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

PS: Random-чика что-то не видать, без него народ во все тяжкие пустился Smile
У Вас тут мафия своя...))) COSA NOSTRA от CFTCLUB


Ну так не проблема же, сделать справочник, в котором класс операции, имя операции и массив истории запуска. В массиве дата и время запуска, лог исполнения (главное не переполнять), запустивший пользователь, опционально - еще колонка для параметров запуска операции. Ну и в автономной транзакции (на случай аварийного завершения при отсутствии обработчика, главное без ссылок на создаваемые объекты) писать туда инфо при каждом запуске.



Справочник со всеми параметрами, необходимыми для запуска уже есть, вместе с job ами всё крутится ~ 4 месяца, дозрел до массива с сообщениями

В массиве
дата и время запуска, ...ok...
лог исполнения (главное не переполнять), ...здесь какой тип посоветуете использовать?
запустивший пользователь...ok...
опционально - еще колонка для параметров запуска операции. ...ok...
Ну и в автономной транзакции (на случай аварийного завершения при
отсутствии обработчика, главное без ссылок на создаваемые объекты) писать туда инфо при каждом запуске. ...тут можно поподробнее, что за автономная транзакция?
prankster
Профи


Вступление в Клуб: 22.08.2014
СообщениеСр Авг 05, 2015 12:53    Ответить с цитатой
Полезность: 1
Матвеев Евгений пишет:
prankster пишет:
Матвеев Евгений пишет:
Спасиб.
Посмотрю.
Вообще хотелось бы, конечно, (ну это в идеале) для каждой своей запускаемой JOB операции сохранять в соответствующей записи справочника с параметрами (а лучше массив структуры) историю системных сообщений запуска...

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

PS: Random-чика что-то не видать, без него народ во все тяжкие пустился Smile
У Вас тут мафия своя...))) COSA NOSTRA от CFTCLUB


Ну так не проблема же, сделать справочник, в котором класс операции, имя операции и массив истории запуска. В массиве дата и время запуска, лог исполнения (главное не переполнять), запустивший пользователь, опционально - еще колонка для параметров запуска операции. Ну и в автономной транзакции (на случай аварийного завершения при отсутствии обработчика, главное без ссылок на создаваемые объекты) писать туда инфо при каждом запуске.



Справочник со всеми параметрами, необходимыми для запуска уже есть, вместе с job ами всё крутится ~ 4 месяца, дозрел до массива с сообщениями

В массиве
дата и время запуска, ...ok...
лог исполнения (главное не переполнять), ...здесь какой тип посоветуете использовать?
запустивший пользователь...ok...
опционально - еще колонка для параметров запуска операции. ...ok...
Ну и в автономной транзакции (на случай аварийного завершения при
отсутствии обработчика, главное без ссылок на создаваемые объекты) писать туда инфо при каждом запуске. ...тут можно поподробнее, что за автономная транзакция?


Если обрезать лог до 32 КБ нельзя, и если 32 КБ не хватит, то только Clob наверн..

А по автономной транзакции - использовать в случае если возможен откат блока, в котором происходит запись в справочник лога, а знать об этом запуске необходимо (иначе при откате экземпляр справочника лога тоже пропадет).

В процедуре (или операции, [NEW_AUTO] например) добавления/обновления экземпляра лога добавить pragma autonomous_transaction; в секции объявления переменных основного блока и обязательный commit перед выходом из процедуры/операции.
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеСр Авг 05, 2015 13:22    Ответить с цитатой
Полезность: Нет оценки
Спасибо коллеги, буду анализировать полученную информацию...
Потом напишу что получилось...
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Уроки ЦФТ-Банк для начинающих Часовой пояс: GMT + 3
На страницу 1, 2  След.
Страница 1 из 2

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru