При эксплуатации крупных систем на базе «1С:Предприятие» под управлением СУБД Oracle системные администраторы и разработчики иногда сталкиваются с загадочным поведением планировщика заданий JobScheduler. В технологическом журнале это проявляется в виде каскада ошибок DataBaseException с кодом ORA-00942: таблица или представление пользователя не существует. Ситуация осложняется тем, что ошибка может возникать циклично, создавая лишнюю нагрузку на сервер и мешая выполнению регламентных операций.
В этой статье мы подробно разберем, почему возникает эта ошибка, как проанализировать записи технологического журнала и какие конкретные шаги нужно предпринять на стороне СУБД Oracle, чтобы нормализовать работу системы.
Рассмотрим ситуацию, представленную в логах технологического журнала. Мы видим, что процесс rphost при выполнении задач планировщика JobScheduler инициирует запросы, которые завершаются аварийно. Проанализируем ключевой фрагмент лога:
00:32.946017-0,EXCP,3,process=rphost,p:processName=PVDBILL,t:clientID=12,t:applicationName=JobScheduler,t:computerName=Server1C82,Exception=DataBaseException,Descr='Ошибка СУБД:
ORA-00942: таблица или представление пользователя не существует'
Сразу за этим событием следует контекст исключения, который раскрывает нам «виновника». Система пытается выполнить SQL-запрос к системным представлениям динамической производительности Oracle:
Sql="SELECT /*+ NO_CPU_COSTING */ BLOCKED.SID, BLOCKER.SID FROM V$LOCK BLOCKER
INNER JOIN V$LOCK BLOCKED ON BLOCKER.ID1 = BLOCKED.ID1 AND BLOCKER.ID2 = BLOCKED.ID2
AND BLOCKED.BLOCK = 0 AND BLOCKED.LMODE = 0 AND BLOCKED.TYPE = 'TX'
WHERE BLOCKER.BLOCK = 1 AND BLOCKER.REQUEST = 0 AND BLOCKER.TYPE = 'TX'"
Проанализируем ситуацию: почему 1С вообще обращается к таблице V$LOCK? Это происходит потому, что платформа 1С обладает встроенными механизмами самодиагностики блокировок. Когда какой-либо прикладной запрос (например, обновление статуса регламентного задания в таблице Config или Params) наталкивается на ожидание блокировки, сервер 1С пытается самостоятельно выяснить, какой сеанс (SID) в Oracle удерживает нужный ресурс. Для этого он обращается к системным вьюхам СУБД. Если у пользователя, под которым 1С подключена к базе, нет прав на эти вьюхи, мы получаем ORA-00942.
Часто в консоли кластера или в логах можно заметить странное поведение: запускается несколько процессов JobScheduler, причем некоторые из них выглядят как «анонимные» (без указания конкретной базы). Рассмотрим, почему так происходит:
rphost может запускать внутренние потоки для управления сервисами кластера.COMConnector), которые пытаются обращаться к несуществующим базам данных в блоках Попытка...Исключение.Чтобы точно понять, какой именно запрос предшествует ошибке, нам необходимо настроить детальный сбор событий. Отредактируем файл logcfg.xml, добавив в него отслеживание событий работы с Oracle. Разберем пример настройки:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<dump location="C:\Dumps" create="true" save="10"/>
<log location="C:\Logs\OracleError" history="24">
<event>
<eq property="Name" value="DBORACLE"/>
</event>
<event>
<eq property="Name" value="EXCP"/>
</event>
<property name="All"/>
</log>
</config>
Использование события DBORACLE позволит нам увидеть не только системный запрос к V$LOCK, но и тот изначальный прикладной SQL-запрос, который вызвал блокировку. Это поможет определить, какая именно таблица 1С (например, _ScheduledJobs) вызывает конфликты доступа.
Основное решение проблемы ORA-00942 при обращении к V$LOCK и V$SESSION заключается в делегировании необходимых привилегий пользователю базы данных 1С. Важно понимать, что в Oracle V$ объекты являются публичными синонимами для динамических представлений, владельцем которых является пользователь SYS.
Выясним причину неудачи: стандартных ролей CONNECT и RESOURCE недостаточно для чтения словаря данных. Для исправления ситуации необходимо подключиться к Oracle под учетной записью с правами SYSDBA и выполнить следующие команды (замените USER_1C на имя вашего пользователя):
GRANT SELECT ON V_$SESSION TO USER_1C;
GRANT SELECT ON V_$LOCK TO USER_1C;
GRANT SELECT ON V_$TRANSACTION TO USER_1C;
GRANT SELECT ON V_$PROCESS TO USER_1C;
GRANT SELECT ON V_$LOCKED_OBJECT TO USER_1C;
GRANT SELECT ON V_$SQL TO USER_1C;
Важное замечание: Обратите внимание, что права выдаются на объекты с именами V_$ИМЯ (с подчеркиванием), а не V$ИМЯ. Это связано с внутренней структурой Oracle: V$LOCK — это синоним, а V_$LOCK — реальное представление. Прямое назначение прав на синонимы может не сработать в некоторых версиях СУБД.
Если в ходе анализа выяснилось, что ошибка провоцируется внешними скриптами или обработками, которые используют COM-соединение для передачи Журнала Регистрации или других данных, проанализируем следующий алгоритм исправления:
COMConnector или вызова Connect, необходимо убедиться, что строка соединения актуальна.Исключение, записывайте подробности ошибки в текстовый файл или локальный журнал регистрации.Пример правильной обработки попытки соединения в регламентном задании:
Попытка
COMОбъект = Новый COMОбъект("V83.COMConnector");
Соединение = COMОбъект.Connect(СтрокаСоединения);
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось подключиться к базе для выгрузки ЖР: " + ОписаниеОшибки());
// Обязательно выходим из процедуры, чтобы не плодить ошибки в JobScheduler
Возврат;
КонецПопытки;
Ошибка ORA-00942 в контексте JobScheduler — это чаще всего лишь «эхо» другой проблемы. Платформа 1С пытается помочь вам найти причину блокировки, но спотыкается об отсутствие прав в Oracle. Выполнив настройку привилегий SELECT на системные вьюхи и проверив корректность работы регламентных заданий, использующих внешние соединения, вы обеспечите стабильную работу сервера приложений и СУБД.
Помните, что для версий 1С 8.2 также критично наличие прав на чтение таблиц SYS.DBA_TABLESPACES и SYS.DBA_DATA_FILES, если платформа пытается анализировать свободное место в табличных пространствах.