В процессе администрирования клиент-серверных баз данных «1С:Предприятия» можно столкнуться с крайне запутанной аномалией: регламентные задания начинают выполняться будущей датой. Например, на календаре сегодня 4-е число, а в столбцах Дата начала и Дата окончания в консоли регламентных заданий отображается 12-е число. При этом попытка проанализировать ситуацию через стандартный Журнал регистрации ни к чему не приводит — система показывает, что записей нет.
В рамках этой статьи мы подробно разберем, почему возникает этот сбой, по какому механизму «фантомные» запуски блокируют работу планировщика 1С, как локализовать проблему с помощью программного кода и как вернуть систему в рабочее состояние без кардинального пересоздания баз данных.
---
Такое поведение системы не является случайным багом платформы. Это логическое следствие цепочки событий, связанных с системным временем. Давайте проанализируем этот механизм по шагам:
Когда администратор нажимает кнопку просмотра журнала регистрации непосредственно из формы регламентного задания, платформа открывает его с автоматическим отбором по умолчанию. Фильтр устанавливается на **текущий день** по системному времени (в нашем примере — на 4-е число).
Записи о выполнении фонового задания физически присутствуют в файлах журнала регистрации, но они записаны той самой **будущей датой** (12-м числом). Чтобы их увидеть, нам достаточно снять ограничение периода в Журнале регистрации или вручную сдвинуть дату окончания фильтра далеко в будущее. Как только мы это сделаем, все «фантомные» записи сразу отобразятся на экране.
---
Если в вашей ИТ-инфраструктуре развернуто несколько копий баз данных (тестовые, учебные, копии для разработки), высока вероятность, что задание запустилось на одной из копий, где при первом старте забыли выбрать опцию «Это копия информационной базы». В результате тестовая база подключилась к рабочим ресурсам или перезаписала данные планировщика.
Давайте рассмотрим, как программно определить, на каком сервере, под каким пользователем и в какой именно базе данных фактически выполняется регламентное задание. Для этого мы можем внедрить простейший диагностический код в само регламентное задание (или временно переписать его обработчик во внешней обработке):
Процедура ЗаписатьЛогДиагностики() Экспорт
ИмяФайлаЛога = "C:\temp\diagnostic_1c_jobs.txt";
// Открываем файл в режиме дополнения текста
ЛогФайл = Новый ЗаписьТекста(ИмяФайлаЛога, КодировкаТекста.UTF8,, Истина);
ТекущееВремя = ТекущаяДата();
ИмяКомпьютера = ИмяКомпьютера();
СтрокаСоединения = СтрокаСоединенияИБ();
// Получаем текущего пользователя системы
Попытка
ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;
Исключение
ТекущийПользователь = "Не определен (запуск под системной учетной записью)";
КонецПопытки;
ШаблонЗаписи = "[%1] Компьютер: %2 | База данных: %3 | Пользователь: %4";
СтрокаЛога = Шаблон(ШаблонЗаписи, ТекущееВремя, ИмяКомпьютера, СтрокаСоединения, ТекущийПользователь);
ЛогФайл.ЗаписатьСтроку(СтрокаЛога);
ЛогФайл.Закрыть();
КонецПроцедуры
После обновления конфигурации базы данных при следующем выполнении задания на сервере в каталоге C:\temp\ появится файл с подробной информацией. Проанализировав строку соединения СтрокаСоединенияИБ() и сетевое имя ПК ИмяКомпьютера(), мы мгновенно поймем, какая база данных шлет некорректные запросы.
---
Если регламентные задания «улетели» в будущее, перенос базы данных на новый SQL-сервер (который сбрасывает метаданные планировщика) — это радикальная и трудоемкая процедура. Рассмотрим два более простых и быстрых способа вернуть планировщик в нормальное состояние.
Самый простой и безопасный способ «обнулить» дату последнего запуска для нетиповых или пользовательских регламентных заданий — пересоздать их:
Новый элемент запишется в систему с пустой датой последнего запуска (значение по умолчанию 0001-01-01), и планировщик начнет выполнять его по текущему времени сервера.
Если задание является предопределенным и удалить его интерактивно кнопкой «Удалить» невозможно, мы можем прибегнуть к программному сбросу расписания с помощью внешней обработки. Разберем пример кода для сброса предопределенного задания:
// Сброс использования предопределенного регламентного задания
ИмяПредопределенного = "ОбновлениеИндексаПолнотекстовогоПоиска";
МетаданныеЗадания = Метаданные.РегламентныеЗадания[ИмяПредопределенного];
НайденноеЗадание = РегламентныеЗадания.НайтиПредопределенное(МетаданныеЗадания);
Если НайденноеЗадание <> Неопределено Тогда
// Отключаем использование задания
НайденноеЗадание.Использование = Ложь;
НайденноеЗадание.Записать();
// Очищаем расписание, переводя его в состояние по умолчанию
НайденноеЗадание.Расписание = Новый РасписаниеРегламентногоЗадания;
НайденноеЗадание.Записать();
Сообщить("Предопределенное задание успешно отключено и сброшено. Настройте расписание заново.");
КонецЕсли;
Вся информация о регламентных заданиях, включая расписание и временные метки их последнего выполнения, хранится непосредственно в таблицах базы SQL. Для клиент-серверных версий 1С мы можем скорректировать эти данные напрямую.
Важное предупреждение: Любые прямые изменения в таблицах SQL выполняются только на собственный страх и риск после создания резервной копии базы данных!
_ScheduledJobs.rphost). Если этого не сделать, менеджер кластера продолжит использовать старые «будущие» значения, сохраненные в его оперативной памяти (кеше).Своевременный контроль системного времени на всех серверах контура и корректная изоляция тестовых баз данных позволят вам избежать подобных сбоев планировщика в будущем.