При использовании платформы 1С:Предприятие 8.3 системные администраторы и разработчики часто сталкиваются с ситуацией, когда работа пользователей полностью блокируется на продолжительное время (от нескольких минут до получаса). При анализе каталога с журналом регистрации обнаруживается странное поведение: основной файл 1Cv8.lgd остается стабильного размера, но рядом с ним появляется и стремительно растет файл 1Cv8.lgd-journal. Рассмотрим подробнее, почему это происходит и как вернуть системе работоспособность.
Для начала выясним, что представляет собой этот файл. Начиная с версии 8.3.5, 1С по умолчанию использует формат журнала регистрации на базе SQLite. Файл с расширением -journal является так называемым откатно-транзакционным журналом (rollback journal).
Проанализируем алгоритм его работы: когда база данных SQLite (в нашем случае это журнал регистрации) готовится изменить данные, она копирует исходное состояние изменяемых страниц в этот временный файл. Если транзакция завершится успешно, файл удаляется или очищается. Если произойдет сбой — данные из него восстанавливаются в основной файл. Критический момент заключается в том, что на время активной записи в этот журнал SQLite накладывает эксклюзивную блокировку на всю базу данных ЖР. Любая попытка другого процесса 1С записать событие в журнал (а 1С пишет туда почти всё: от входа пользователя до записи любого документа) приводит к ожиданию, которое пользователь видит как полное «зависание» интерфейса.
Почему же файл журнала транзакций может вырасти до сотен мегабайт и парализовать работу? Разберем основные сценарии:
ОтменитьТранзакцию(), платформа должна пометить все записи в журнале регистрации, сделанные в рамках этой транзакции, как «отмененные». Для этого выполняется SQL-запрос UPDATE. Если транзакция была огромной (например, групповое перепроведение документов или загрузка данных), SQLite приходится обновлять тысячи строк. Это вызывает массовое копирование страниц в 1Cv8.lgd-journal и длительную блокировку.1Cv8.lgd-journal начинает активно расти, антивирус может расценить это как подозрительную активность и заблокировать доступ к файлу для проверки. В результате процесс rmngr не может завершить транзакцию и «виснет» вместе со всеми сессиями пользователей.1Cv8.lgd может быть нарушена. Это приводит к тому, что простые операции записи начинают требовать перестроения страниц базы данных, что многократно увеличивает нагрузку на дисковую подсистему.Практика эксплуатации высоконагруженных систем показывает, что формат SQLite (.lgd) плохо справляется с интенсивной записью. Самым надежным решением является возврат к классическому текстовому формату (.elf). Рассмотрим, как это сделать.
Посмотрим на пример настройки через конфигуратор:
Если интерфейс не позволяет сменить формат (в некоторых релизах это заблокировано), воспользуемся методом программного переключения. Для этого можно создать внешнюю обработку и использовать следующий код:
// Устанавливаем текстовый формат журнала регистрации
НовыйФормат = ФорматЖурналаРегистрации.Текстовый;
УстановитьФорматЖурналаРегистрации(НовыйФормат);
Важное преимущество текстового формата: запись в него происходит методом append (добавление в конец файла). Это не требует сложных транзакционных механизмов и блокировок всей базы, что исключает «фризы» интерфейса из-за ЖР.
Если по каким-то причинам вы решили остаться на формате SQLite, проанализируем шаги по его оптимизации:
1Cv8.lgd разрастаться свыше 2–4 Гб. Настройте разделение журнала по периодам (например, по дням или неделям). Чем меньше размер файла базы данных SQLite, тем быстрее выполняются операции обновления статуса транзакций.*.lgd, *.lgd-journal, *.lgd-wal и *.lgc в список исключений антивирусного сканера на всех серверах кластера.Write-Ahead Logging, который позволяет одновременно читать и писать в базу без взаимных блокировок. Однако стоит помнить, что 1С управляет файлом ЖР самостоятельно, и принудительное включение WAL через сторонние утилиты может быть сброшено платформой при перезапуске службы.Если вы используете метод ВыгрузитьЖурналРегистрации(), помните, что неправильно составленный отбор может спровоцировать те самые тормоза. Посмотрим на пример кода, который может вызвать проблемы на больших объемах данных:
// Неоптимальный отбор по части строки комментария
Отбор = Новый Структура;
Отбор.Вставить("Комментарий", "Ошибка"); // Индекса по комментарию нет!
Журнал = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(Журнал, Отбор);
В этом случае платформа будет вынуждена просканировать весь файл 1Cv8.lgd. Если в этот момент система попытается выполнить rollback какой-то транзакции, вы получите «мертвую блокировку». Старайтесь всегда использовать в отборах индексированные поля: Период, Пользователь, Событие.
Подведем итог: внезапный рост 1Cv8.lgd-journal — это симптом «захлебывания» базы данных SQLite при попытке выполнить массовое изменение записей. Наиболее эффективным методом борьбы с этим остается использование старого доброго текстового формата, который лишен проблем с транзакционными блокировками.