В практике работы с платформой «1С:Предприятие 8.2» и более поздними версиями иногда возникает критическая ситуация: данные из регистра сведений исчезают, но стандартный поиск в Журнале регистрации (ЖР) по событию «Удаление» не дает никаких результатов. Это создает иллюзию «самопроизвольного» очищения базы. В данной статье мы подробно разберем технические причины такого поведения платформы, проанализируем механизмы записи наборов данных и выясним, где искать следы пропавших записей.
Первое, что нам необходимо усвоить: платформа 1С воспринимает работу с регистрами сведений иначе, чем с объектными данными (справочниками или документами). Для справочника удаление — это конкретное событие Удаление. Для регистра сведений любое изменение состава записей чаще всего фиксируется как событие «Данные. Изменение».
Разберем ситуацию: если пользователь или внешняя обработка удаляет записи, в Журнале регистрации в колонке «Событие» мы не увидим слова «Удаление». Мы увидим «Изменение», а в колонке «Данные» будет указан конкретный регистр. Это происходит потому, что запись в регистр сведений всегда осуществляется через НаборЗаписей. Платформа считает, что вы не «удалили объект», а «изменили состояние регистра», записав в него новый (возможно, пустой) набор данных.
Рассмотрим самый распространенный сценарий, при котором данные пропадают массово, а записей в журнале оказывается подозрительно мало. Это использование метода Записать(Истина). Проанализируем пример кода, который часто становится причиной потери данных:
Набор = РегистрыСведений.ПаспортныеДанныеФизЛиц.СоздатьНаборЗаписей();
Набор.Отбор.ФизЛицо.Установить(ВыбФизЛицо);
// Если мы не заполняем набор новыми записями и вызываем Записать(Истина)
Набор.Записать(Истина);
Выясним, что происходит в этот момент на уровне СУБД и Журнала регистрации. Параметр Истина (замещение) заставляет платформу сначала удалить все существующие записи, подпадающие под установленный отбор, а затем записать те, что содержатся в объекте Набор в оперативной памяти. Если в наборе было всего 2 записи, а в базе по этому отбору — 370, то платформа удалит 370 и запишет 2. При этом в Журнале регистрации появится всего одна запись о событии «Изменение», так как это была одна транзакция записи набора.
Если же отбор не был установлен вовсе, а метод Записать(Истина) был вызван для пустого набора, весь регистр будет очищен мгновенно, и об этом также будет свидетельствовать лишь одна скромная строчка в ЖР.
Иногда программисты используют специальное свойство для ускорения работы или обхода проверок: ОбменДанными.Загрузка = Истина. Посмотрим на пример:
Набор = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();
При использовании этого режима многие подписки на события и внутренние механизмы контроля платформы отключаются. Хотя запись в Журнал регистрации все равно должна произойти, при массовых операциях в рамках обмена данными записи могут группироваться или иметь специфическое представление (например, относиться к событию «Данные.Обмен»), что затрудняет их поиск обычным фильтром по «Удалению».
Если мы уверены, что поиск ведется правильно (по событию «Изменение»), но записей все равно нет, проанализируем состояние самой системы логирования:
.log и .lgp. При достижении файлом объема в несколько гигабайт или при нехватке места на диске, новые записи могут перестать добавляться, хотя база данных продолжит работать..lki) поврежден. В таком случае через интерфейс 1С данные поиска будут отображаться некорректно. Попробуйте просмотреть файлы журнала сторонними текстовыми редакторами или специальными утилитами.Рассмотрим ситуацию, когда данные пропадают в результате административных действий. Существует два важных механизма:
Реструктуризация: Если в конфигурации был изменен тип измерения регистра или состав ключа уникальности, при обновлении конфигурации базы данных (F7) платформа перестраивает таблицы. Если старые данные не «пролезают» в новые типы или нарушают уникальность, они могут быть удалены или схлопнуты. В ЖР это отразится как «Принятие изменений конфигурации», без детализации по каждой записи регистра.
Тестирование и исправление (ТиИ): Если запустить ТиИ с включенной опцией «Очищать записи» при наличии ссылок на несуществующие объекты, платформа удалит записи в регистрах сведений, которые ссылаются на удаленные элементы справочников (например, если физлицо было удалено напрямую из СУБД или при сбое). Это действие будет зафиксировано как событие «Тестирование и исправление», а не как пользовательское удаление.
Если база работает в клиент-серверном варианте, нельзя исключать манипуляции на уровне СУБД. Команды типа TRUNCATE TABLE или DELETE FROM, выполненные системным администратором через SQL Server Management Studio, полностью обходят механизмы 1С. Журнал регистрации 1С в принципе не способен зафиксировать такие действия.
Для расследования подобных инцидентов в будущем рекомендуем настроить Технологический журнал. В отличие от Журнала регистрации, он фиксирует все SQL-запросы, отправляемые платформой к серверу баз данных. Настроив сбор события DBMSSQL, можно точно увидеть, какой сеанс инициировал удаление записей:
<event query="DBMSSQL">
<f filter="Context" />
<f filter="Sql" />
</event>
Проанализировав такой лог, вы сможете увидеть запрос DELETE FROM _InfoRegXXX, где XXX — номер таблицы вашего регистра, и по контексту понять, какая обработка или фоновое задание вызвали потерю данных.
Подводя итог, можно сказать: данные из РС «просто так» не пропадают. Если их нет в ЖР по фильтру «Удаление», необходимо расширить область поиска:
НаборЗаписей с методом Записать(Истина), так как это самая частая причина массовой потери данных при ошибках в алгоритмах отборов.