Как узнать, кто удалил записи регистра сведений в 1С, если журнал регистрации был выключен

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Ситуация, когда из базы данных исчезают важные записи регистра сведений, а Журнал регистрации 1С настроен на запись только ошибок, является критической для любого администратора или программиста. В такой ситуации стандартные средства платформы не дают ответа на вопрос "Кто это сделал?". Однако информация не исчезает бесследно. Мы разберем, как восстановить хронологию событий, используя возможности СУБД MS SQL Server и механизмы самой платформы 1С.

Этап 1. Определение целевой таблицы в MS SQL Server

Прежде чем приступать к поиску в логах SQL-сервера, нам необходимо выяснить техническое имя таблицы, которая соответствует нашему регистру сведений. В 1С имена таблиц в базе данных имеют вид _InfoRgXXXX, где XXXX — это порядковый номер. Для того чтобы узнать точное имя, мы воспользуемся встроенной функцией платформы.

Выполним следующий программный код в консоли кода или внешней обработке:


Выборка = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Таблица Из Выборка Цикл
    Если Таблица.ИмяТаблицы = "РегистрСведений.ИмяВашегоРегистра" Тогда
        Сообщить("Имя таблицы в SQL: " + Таблица.ИмяТаблицыХранения);
    КонецЕсли;
КонецЦикла;

Запомним полученное имя (например, _InfoRg1234). Теперь мы знаем, где именно искать следы удаления.

Этап 2. Анализ лога транзакций SQL Server (LDF)

MS SQL Server записывает все изменения данных в файл лога транзакций (.ldf). Даже если у вас установлена модель восстановления Simple, записи об удалении кратковременно сохраняются там до момента перезаписи лога. Если же установлена модель Full, шансы найти информацию значительно выше.

Проанализируем содержимое лога с помощью недокументированной системной функции fn_dblog. Откроем SQL Server Management Studio (SSMS) и выполним запрос:


SELECT 
    [Current LSN], 
    [Operation], 
    [Transaction ID], 
    [Begin Time], 
    [Transaction Name],
    [Transaction SID]
FROM sys.fn_dblog(NULL, NULL)
WHERE [AllocUnitName] LIKE '%_InfoRg1234%' -- подставьте ваше имя таблицы
AND [Operation] = 'LOP_DELETE_ROWS';

Рассмотрим, что мы получим в результате:

  1. Operation: Подтверждает факт удаления (LOP_DELETE_ROWS).
  2. Begin Time: Точное время, когда была инициирована транзакция удаления.
  3. Transaction SID: Идентификатор безопасности пользователя SQL.

Важный нюанс: В большинстве случаев в поле пользователя вы увидите sa или учетную запись, под которой работает служба сервера 1С:Предприятие. Это происходит потому, что 1С работает с базой данных через пул соединений, и для SQL-сервера все действия выполняет один и тот же "технический" пользователь.

Этап 3. Сопоставление данных через Технологический журнал (ТЖ)

Чтобы понять, какой именно пользователь 1С инициировал SQL-запрос на удаление, нам потребуется Технологический журнал. Если он был включен заранее, это решит проблему. Если нет — его стоит включить сразу после обнаружения пропажи, чтобы зафиксировать возможные повторные действия.

Для поиска виновника нам нужно настроить сбор событий DBMSSQL. В файле настроек logcfg.xml это выглядит примерно так:


<config xmlns="http://v8.1c.ru/7.4/get/logcfg">
  <log location="C:\Logs\SQLQueries" history="168">
    <event>
      <eq property="Name" value="DBMSSQL"/>
      <like property="Sql" value="%DELETE FROM _InfoRg1234%"/>
    </event>
    <property name="All"/>
  </log>
</config>

Проанализируем логи ТЖ, которые появятся в папке C:\Logs\SQLQueries. Каждое событие будет содержать:

Зная SessionID и время из SQL-лога, мы можем легко вычислить имя пользователя в 1С, сопоставив эти данные.

Этап 4. Использование сторонних утилит (Log Readers)

Если ручной анализ fn_dblog кажется слишком сложным, рассмотрим специализированные инструменты, такие как ApexSQL Log или аналоги. Эти программы позволяют визуализировать файл .ldf и показывают удаленные строки в удобном виде.

Преимущества этого метода:

Этап 5. Метод сравнения с резервной копией

Если нам не удалось выяснить "кто", крайне важно понять "что" именно было удалено. Для этого проанализируем ситуацию методом сравнения текущего состояния базы с бэкапом.

  1. Развернем последний живой бэкап базы под другим именем (например, Base_Work_Copy).
  2. Выполним SQL-запрос для поиска различий между таблицами в основной базе и в копии.

SELECT * FROM [Base_Work_Copy].[dbo].[_InfoRg1234]
EXCEPT
SELECT * FROM [Current_Base].[dbo].[_InfoRg1234];

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

Выясняем причину: системная ошибка или злой умысел?

Часто удаление записей регистра происходит не вручную, а программно. Рассмотрим ситуацию: программист написал обработку, в которой используется НаборЗаписей регистра сведений. Если при записи набора не установить Отбор, то при выполнении метода Записать(Истина) 1С полностью очистит все записи регистра, соответствующие (в данном случае — пустые) фильтрам.

Как это проверить: В логах Технологического журнала (ТЖ) ищите события DBMSSQL, где запрос начинается с DELETE FROM _InfoRg1234 без секции WHERE. Это верный признак того, что отработал некорректный программный код, а не ручное удаление строк пользователем.

Подводя итог, можно сказать: несмотря на выключенный журнал регистрации, комбинация анализа SQL-транзакций, сопоставления с бэкапами и настройки Технологического журнала позволяет с высокой точностью определить время, объем удаленных данных и, в большинстве случаев, конкретный сеанс пользователя 1С.

← На главную