Как открыть журнал регистрации 1С объемом 20 ГБ и найти изменения константы без зависания системы?

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

Каждый администратор крупных баз данных 1С рано или поздно сталкивается с критическим падением производительности при попытке проанализировать журнал регистрации. Ситуация, когда файл журнала разрастается до 20 ГБ и более, а простая попытка установить отбор по метаданным константы намертво «вешает» сервер 1С и съедает всю доступную оперативную память, весьма распространена.

В этой статье мы подробно разберем, почему платформа 1С:Предприятие (в особенности на версиях 8.3.13) начинает неконтролируемо потреблять ОЗУ при поиске в больших логах, и рассмотрим пошаговые практические методы извлечения нужных данных без вреда для стабильности работающей системы.

Выясняем причину: почему происходит лавинообразный «жор» памяти?

Начиная с версии платформы 8.3.12, фирма «1С» внедрила новый формат журнала регистрации, использующий под капотом встроенную СУБД SQLite (файлы с расширением .lgd). Данное нововведение должно было повысить скорость работы с логами, однако на практике привело к ряду серьезных проблем:

Важное примечание: Проблемы с форматом .lgd оказались настолько серьезными, что в более новых версиях платформы (начиная с 8.3.22) фирма «1С» полностью отказалась от формата SQLite, вернув надежный текстовый формат как единственный стандартный вариант.

---

Способ 1. Прямой обход платформы через SQL-запросы к файлу 1Cv8.lgd

Если нам необходимо всего лишь узнать, какой пользователь и когда изменил значение конкретной константы, самым быстрым и безопасным решением будет чтение файла базы данных SQLite напрямую, в обход зависающих механизмов 1С. Для этого мы применим сторонний менеджер баз данных (например, бесплатную утилиту DB Browser for SQLite или DBeaver).

Проанализируем и выполним этот процесс по шагам:

  1. Остановим службу сервера 1С:Предприятие или закроем файловую базу, чтобы освободить файл от монопольного доступа.
  2. Скопируем рабочий файл журнала регистрации 1Cv8.lgd из каталога 1Cv8Log информационной базы в любую временную папку на локальном компьютере. Никогда не выполняйте запросы напрямую к рабочему логу на сервере!
  3. Запустим DB Browser for SQLite и откроем скопированный файл лога.
  4. Перейдем на вкладку выполнения SQL-запросов. Нам нужно определить внутренний идентификатор нашей константы в таблице метаданных. Выполним следующий поисковый запрос:

SELECT code, name FROM MetadataCodes WHERE name LIKE '%ИмяВашейКонстанты%';

Предположим, в результате выполнения запроса мы получили значение code = 45. Теперь мы можем извлечь историю изменений этой константы. Составим и запустим оптимизированный запрос, связывающий таблицы логов и пользователей.

Обратите внимание: 1С хранит временные метки в SQLite в виде десятых долей микросекунд (тиков), прошедших с начала нашей эры. Для преобразования этого числа в понятный формат даты и времени в SQL-запросе используется математическая формула пересчета в Unix Epoch:


SELECT 
    datetime(el.date/10000 - 62135596800, 'unixepoch', 'localtime') AS [Дата и время],
    uc.name AS [Пользователь],
    el.dataPresentation AS [Новое значение]
FROM EventLog el
JOIN EventLogMetadata elm ON el.rowID = elm.eventLogID
LEFT JOIN UserCodes uc ON el.userCode = uc.code
WHERE elm.metadataCode = 45
ORDER BY el.date DESC
LIMIT 100;

Этот запрос отработает за считанные секунды даже на 20-гигабайтном файле, поскольку выборка происходит по индексированному полю metadataCode и ограничивается первыми 100 результатами.

---

Способ 2. Восстановление поврежденного файла журнала регистрации

Если при попытке выполнить SQL-запрос СУБД возвращает ошибку database disk image is malformed, это явный признак того, что файл журнала поврежден. Нам потребуется «вылечить» базу данных, пересобрав ее из текстового дампа с помощью консольной утилиты sqlite3.exe.

Рассмотрим последовательность действий для восстановления:

  1. Скачаем консольную утилиту sqlite3.exe с официального сайта разработчиков SQLite и поместим ее в одну папку с копией нашего битого файла лога.
  2. Откроем командную строку Windows (cmd) и перейдем в эту папку. Экспортируем всю структуру и данные поврежденного лога в текстовый файл SQL-инструкций:

sqlite3.exe 1Cv8.lgd .dump > dump.sql

  1. Откроем полученный файл dump.sql в любом мощном текстовом редакторе (например, Notepad++). Прокрутим файл в самый конец. Если последней строкой файла идет инструкция ROLLBACK; (что означает аварийное прерывание транзакции), заменим ее вручную на слово COMMIT; и сохраним изменения.
  2. Сформируем абсолютно новую, чистую базу данных журнала регистрации из исправленного текстового дампа:

sqlite3.exe 1Cv8_fixed.lgd < dump.sql

  1. Для окончательного выстраивания индексов и минимизации физического объема файла выполним команду сжатия базы:

sqlite3.exe 1Cv8_fixed.gd "VACUUM;"

После завершения процедур файл 1Cv8_fixed.lgd можно переименовать обратно в 1Cv8.lgd. Теперь он полностью работоспособен, не содержит логических ошибок и готов к быстрому чтению.

---

Способ 3. Безопасная выгрузка данных программным методом 1С

Если вы хотите решить задачу без использования внешних СУБД, исключительно внутри платформы 1С:Предприятие, никогда не открывайте журнал регистрации интерактивно через Конфигуратор на таких объемах данных. Вместо этого напишем простую внешнюю обработку и запустим ее на сервере.

Использование встроенного метода ВыгрузитьЖурналРегистрации() со строгим ограничением периода поиска и фильтрацией по конкретным метаданным не вызывает перегрузки ОЗУ, так как платформа запрашивает у SQLite строго ограниченный массив записей.

Посмотрим на пример кода внешней обработки:


// Создаем структуру отбора
Отбор = Новый Структура;

// Обязательно указываем жесткое ограничение по метаданным константы
Отбор.Вставить("Метаданные", Метаданные.Константы.ИмяНужнойКонстанты);

// Настоятельно рекомендуем сузить период поиска, например, последними 30 днями
Отбор.Вставить("ДатаНачала", НачалоДня(ТекущаяДата() - 30 * 86400)); 

// Инициализируем таблицу для выгрузки результатов
ТаблицаРезультат = Новый ТаблицаЗначений;

// Выполняем быструю выборку на сервере
ВыгрузитьЖурналРегистрации(ТаблицаРезультат, Отбор);

// Теперь ТаблицаРезультат содержит только нужные нам записи, ее можно вывести на форму

---

Способ 4. Переход на классический текстовый формат и настройка разделения логов

Чтобы раз и навсегда предотвратить повторение подобных проблем на базах крупного объема, мы рекомендуем отказаться от нестабильного формата логов SQLite и вернуться к проверенной временем классике.

Давайте разберем алгоритм безопасного перехода обратно на текстовый формат .lgf:

  1. Остановим службу сервера 1С:Предприятие.
  2. Перейдем в каталог 1Cv8Log вашей информационной базы на сервере и перенесем все файлы с расширением .lgd в отдельную архивную папку вне каталога 1С.
  3. В каталоге 1Cv8Log создадим пустой текстовый файл и назовем его 1Cv8.lgf (с пустым содержимым).
  4. Запустим службу сервера 1С. Обнаружив текстовый файл-маркер, платформа автоматически начнет записывать события в классическом текстовом формате.

Для минимизации размеров файлов логов обязательно настроим их разделение по периодам. Для этого в Конфигураторе зайдем в меню Администрирование — Настройка журнала регистрации и выберем периодичность разделения, например, «По неделям» или «По месяцам».

В этом случае вместо одного гигантского файла система будет создавать множество небольших файлов с расширением .lgp. Старые файлы за прошедшие месяцы можно будет легко переносить в архив или удалять обычными средствами операционной системы, а оперативный поиск за текущий период станет мгновенным.

← На главную