Ситуация, когда из базы данных исчезают важные записи регистра сведений, а Журнал регистрации 1С настроен на запись только ошибок, является критической для любого администратора или программиста. В такой ситуации стандартные средства платформы не дают ответа на вопрос "Кто это сделал?". Однако информация не исчезает бесследно. Мы разберем, как восстановить хронологию событий, используя возможности СУБД MS SQL Server и механизмы самой платформы 1С.
Прежде чем приступать к поиску в логах SQL-сервера, нам необходимо выяснить техническое имя таблицы, которая соответствует нашему регистру сведений. В 1С имена таблиц в базе данных имеют вид _InfoRgXXXX, где XXXX — это порядковый номер. Для того чтобы узнать точное имя, мы воспользуемся встроенной функцией платформы.
Выполним следующий программный код в консоли кода или внешней обработке:
Выборка = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Таблица Из Выборка Цикл
Если Таблица.ИмяТаблицы = "РегистрСведений.ИмяВашегоРегистра" Тогда
Сообщить("Имя таблицы в SQL: " + Таблица.ИмяТаблицыХранения);
КонецЕсли;
КонецЦикла;
Запомним полученное имя (например, _InfoRg1234). Теперь мы знаем, где именно искать следы удаления.
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';
Рассмотрим, что мы получим в результате:
LOP_DELETE_ROWS).Важный нюанс: В большинстве случаев в поле пользователя вы увидите sa или учетную запись, под которой работает служба сервера 1С:Предприятие. Это происходит потому, что 1С работает с базой данных через пул соединений, и для SQL-сервера все действия выполняет один и тот же "технический" пользователь.
Чтобы понять, какой именно пользователь 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С, сопоставив эти данные.
Если ручной анализ fn_dblog кажется слишком сложным, рассмотрим специализированные инструменты, такие как ApexSQL Log или аналоги. Эти программы позволяют визуализировать файл .ldf и показывают удаленные строки в удобном виде.
Преимущества этого метода:
Host Name (имя компьютера), с которого пришел запрос, что сужает круг подозреваемых.Если нам не удалось выяснить "кто", крайне важно понять "что" именно было удалено. Для этого проанализируем ситуацию методом сравнения текущего состояния базы с бэкапом.
Base_Work_Copy).
SELECT * FROM [Base_Work_Copy].[dbo].[_InfoRg1234]
EXCEPT
SELECT * FROM [Current_Base].[dbo].[_InfoRg1234];
Этот запрос покажет все записи, которые присутствуют в бэкапе, но отсутствуют в рабочей базе. Проанализировав состав этих данных, мы часто можем сделать логический вывод о том, какая подсистема или какой процесс (например, групповое перепроведение или специфическая обработка очистки) могли привести к такому результату.
Часто удаление записей регистра происходит не вручную, а программно. Рассмотрим ситуацию: программист написал обработку, в которой используется НаборЗаписей регистра сведений. Если при записи набора не установить Отбор, то при выполнении метода Записать(Истина) 1С полностью очистит все записи регистра, соответствующие (в данном случае — пустые) фильтрам.
Как это проверить: В логах Технологического журнала (ТЖ) ищите события DBMSSQL, где запрос начинается с DELETE FROM _InfoRg1234 без секции WHERE. Это верный признак того, что отработал некорректный программный код, а не ручное удаление строк пользователем.
Подводя итог, можно сказать: несмотря на выключенный журнал регистрации, комбинация анализа SQL-транзакций, сопоставления с бэкапами и настройки Технологического журнала позволяет с высокой точностью определить время, объем удаленных данных и, в большинстве случаев, конкретный сеанс пользователя 1С.