Работа с крупными информационными базами «1С:Предприятие» (объемом около 1 Тб и более) накладывает особую ответственность на администраторов СУБД и разработчиков. В процессе эксплуатации таких систем можно столкнуться с крайне загадочным симптомом: при одновременной работе множества пользователей регламентированные отчеты (например, Оборотно-сальдовая ведомость) начинают выдавать разные, постоянно «скачущие» цифры при каждом перезапуске. При этом база данных работает медленно, а сервер СУБД испытывает серьезные нагрузки.
В этой статье мы подробно разберем физику этого процесса, выясним причины сбоев и предложим проверенные практические решения для нормализации работы системы.
---
Для того чтобы понять, почему один и тот же отчет, запущенный с разницей в несколько секунд, выдает разные результаты, нам необходимо обратиться к механизмам работы СУБД MS SQL Server с блокировками. По умолчанию в платформе «1С:Предприятие» большинство запросов на получение данных для отчетов выполняются в режиме так называемого «грязного чтения» (грязное чтение реализуется через хинт NOLOCK или уровень изолированности транзакций READ UNCOMMITTED). Это сделано для того, чтобы тяжелые аналитические отсчеты не блокировали запись новых документов оперативными пользователями.
Однако при высокой интенсивности записи транзакций режим NOLOCK может приводить к двум неприятным физическим явлениям на уровне дисковых страниц СУБД:
NOLOCK проходит по страницам в момент их расщепления, он может прочитать одну и ту же строку дважды (если она переместилась вперед по ходу сканирования) или полностью пропустить ее (если она переместилась назад). Физически в базе данные корректны, но отчет возвращает ложный, «скачущий» результат.Для решения этой проблемы на уровне СУБД применяется перевод базы данных в режим RCSI (Read Committed Snapshot Isolation). В этом режиме читающие запросы всегда видят согласованную версию данных на момент начала запроса, считывая их из версионного хранилища в системной базе tempdb, не накладывая блокировок и не страдая от «грязного» чтения.
Включить данный режим в MS SQL Server можно следующим скриптом:
ALTER DATABASE [ИмяВашейБазы] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [ИмяВашейБазы] SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE [ИмяВашейБазы] SET MULTI_USER;
---
Иногда администраторы замечают, что при формировании отчетов проскальзывают записи с пустой датой (01.01.0001). Давайте разберем, откуда они берутся.
При записи наборов записей регистров платформа 1С использует оптимизированные алгоритмы. Во время транзакции записи движений платформа может сначала очистить существующие движения (записав пустой набор) или временно проинициализировать структуру таблицы со значениями по умолчанию. На физическом уровне СУБД эти строки на короткое время могут получить значения пустой даты.
Если в этот микросекундный интервал времени выполняется тяжелый запрос отчета в режиме NOLOCK, он успевает прочитать эти промежуточные «технические» записи с пустой датой. В результате в ОСВ ломаются входящие остатки, так как движения на пустую дату влияют на расчет итогов по всему периоду. После завершения транзакции СУБД фиксирует корректные даты движений, и при следующем формировании отчета аномалия исчезает.
---
Наиболее частой причиной стабильно неверных данных и колоссальных тормозов при формировании ОСВ является рассинхронизация или отключение итогов регистров за старые периоды.
В системе 1С данные хранятся в двух связанных таблицах: таблице движений (индивидуальные записи документов) и таблице итогов (сгруппированные агрегаты по месяцам). При формировании отчета на определенную дату система не рассчитывает баланс с самого начала ведения учета. Она берет ближайшую рассчитанную точку из таблицы итогов и прибавляет/вычитает к ней движения только за короткий промежуток времени между датой отчета и точкой итогов.
Если итоги за прошлые периоды (например, за 2015-2016 годы) по какой-то причине повреждены или не рассчитаны, происходят следующие критические сбои:
Важно понимать: обычный пересчет итогов за последние несколько месяцев (который часто делают администраторы для экономии времени) не решает проблему, если сбой произошел в более ранних периодах. Необходимо выполнить полный пересчет итогов с самого начала ведения учета.
На терабайтной базе данных стандартный пересчет через режим «Тестирование и исправление» (ТиИ) в монопольном режиме может занять несколько суток, что недопустимо для работающего бизнеса. В такой ситуации мы рекомендуем использовать штатную обработку «Управление итогами» в режиме Предприятия:
Для автоматизации этого процесса в нерабочее время можно использовать программный пересчет с помощью встроенного языка 1С:
ГраницаИтогов = '20120101000000'; // Пример начальной даты
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодРассчитанныхИтогов(ГраницаИтогов);
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтоги();
---
Для стабильной работы крупных баз данных стандартные планы обслуживания MS SQL Server («Планы обслуживания» из графического интерфейса SSMS) не подходят, так как они запускают тяжелые операции без оглядки на текущую нагрузку и размер таблиц.
Давайте рассмотрим комплекс правил «осторожного» обслуживания крупных баз:
REBUILD для всех таблиц подряд. Используйте скрипты (например, популярное решение от Ola Hallengren), которые оценивают процент фрагментации каждого индекса индивидуально:
REORGANIZE), которая не блокирует таблицу и работает в разы быстрее.REBUILD), по возможности с опцией ONLINE = ON (доступно в Enterprise-версиях MS SQL).FULLSCAN по всей базе может «повесить» сервер.
Рекомендуется обновлять статистику выборочно — только для тех таблиц, в которых за сутки изменилось более 10% строк. Для гигантских таблиц движений (таблицы с префиксами _AccumReg и _InfoReg) используйте обновление с ограниченной выборкой (например, WITH SAMPLE 20 PERCENT).
AUTO_UPDATE_STATISTICS_ASYNC (Асинхронное автоматическое обновление статистики). Это позволит избежать ситуации, когда запрос пользователя внезапно «зависает» на несколько минут из-за того, что СУБД решила прямо во время выполнения его запроса пересчитать устаревшую статистику по таблице. При включенной опции запрос выполнится по старому плану, а обновление запустится в фоновом режиме.---
Переход на механизм READ_COMMITTED_SNAPSHOT (RCSI) является стандартом для крупных систем 1С, однако он несет в себе скрытые риски, о которых системный администратор должен знать заранее.
При включении RCSI все изменяемые версии строк транслируются в базу данных TempDB. Для базы объемом 1 Тб с интенсивным вводом документов это означает колоссальный рост нагрузки на дисковую систему, где расположена TempDB. Если подсистема хранения TempDB медленная, вы получите жесткие просадки по производительности всей СУБД.
Для предотвращения этой проблемы выполните оптимизацию TempDB по шагам:
TempDB исключительно на самых быстрых SSD/NVMe дисках в системе.TempDB на несколько файлов данных равного размера. Количество файлов должно соответствовать количеству физических ядер процессора (но не более 8 файлов, если у вас многоядерный сокет, дальнейшее увеличение редко дает прирост).TempDB, чтобы избежать их неравномерного заполнения.---
Иногда «скачущие» остатки в сложных аналитических отчетах вызваны не проблемами с СУБД, а внутренними ошибками самой платформы «1С:Предприятие». В некоторых релизах ветки 8.3 (в частности, до релиза 8.3.11) присутствовал баг в механизме оптимизации запросов Системы компоновки данных (СКД).
При использовании вертикальных группировок по периодам в отчетах, построенных на виртуальных таблицах остатков и оборотов, компоновщик неверно транслировал роли полей остатков в итоговый T-SQL запрос. Это приводило к некорректному соединению таблиц на уровне СУБД и так называемому «размножению остатков» (цифры удваивались или утраивались случайным образом).
Как диагностировать эту проблему: попробуйте временно добавить в группировку отчета поле детальных записей (например, регистратор/документ движения). Если после этого остатки перестали «плясать» и выстроились в корректную цепочку — вы столкнулись именно с багом компоновщика. Решением в данном случае является только обновление технологической платформы «1С:Предприятие» до актуального стабильного релиза.
---
Давайте резюмируем последовательность шагов, которые мы должны предпринять при обнаружении плавающих цифр в отчетах и тормозов на крупной базе 1С:
READ_COMMITTED_SNAPSHOT (RCSI), предварительно оптимизировав дисковую подсистему и структуру файлов базы данных TempDB.