Свёртка, которая не лечит. Часть 3: живые бои на площадке

05.10.26

База данных - HighLoad оптимизация

Третья часть разбора проекта 1С:ERP на 2,5 ТБ — живые бои на площадке: сервер, падавший по памяти, документ, который ждал сам себя, галочка, из-за которой система думала 26 минут, воскресный призрак в статистике и 300 гигабайт файлов внутри базы.

Часть 3. Живые бои на площадке: галочка, воскресный призрак и документ, который ждал сам себя

Это третья часть цикла. В первой базу 2,5 ТБ собрались сворачивать, потому что «слишком большая», — а замеры показали, что ни одна причина нагрузки не связана с объёмом. Во второй мы прошли по музею накопленного за годы: зациклившийся обмен, ночное обслуживание, не доходившее до конца очереди, мёртвые планы обмена на 45 гигабайт и расширение, съедавшее десятки часов процессорного времени. Но самое болезненное для бизнеса происходило не в архитектуре, а на живой линии.

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

 

1. Сервер, который падал по памяти

Сервер приложений падал прямо в смену. Не «тормозил» — падал: кластер убивал рабочий процесс целиком, а вместе с ним все сеансы пользователей и две тысячи фоновых заданий, которые жили в том же процессе.

Причина нашлась в журнале обмена с системой маркировки. Каждый запрос дописывался в один файл, а в конце этот файл целиком читался в память — по 64–144 гигабайта за вызов. Примерно как если бы бухгалтер после каждой операции перечитывал вслух всю книгу учёта с первой страницы — а книга с каждым днём становилась толще.

Логирование отключили — и падения по памяти прекратились. Без единого нового сервера.

Рядом жил дальний родственник той же беды. При печати и эмиссии кодов система отправляла на экран оповещение о ходе работы на каждый код: десять тысяч кодов — десять тысяч оповещений. Сервер это уже не роняло, но копило ожидания и блокировки. Предложение простое — сообщать о прогрессе раз в сто кодов.

 

2. Документ, который ждал сам себя

Оператор оформляет выпуск готовой продукции. Документ зависает на несколько минут, потом падает с ошибкой «в данной транзакции уже происходили ошибки». Оператор повторяет. Снова. Иногда — по кругу.

Разбор протоколов показал редкую по красоте картину. Проведение выпуска внутри своей же транзакции запускало перепроведение всей цепочки связанных документов — десятков штук, даже если в цепочке ничего не менялось. Та же транзакция держала блокировку очереди фоновых заданий производства. А фоновые задания, порождённые этим же проведением, пытались получить эту очередь — и не могли, потому что её держал их собственный родитель. Документ ждал сам себя. Через 20 секунд платформа сдавалась таймаутом, всё откатывалось, и оператор шёл на второй круг.

Из 258 секунд проведения 45 секунд документ считал, а 213 — ждал.

Решение спроектировали: штатный пакетный режим и вынос тяжёлого перепроведения цепочки в фон, а заодно не перепроводить то, что не изменилось. Пока оно ждёт внедрения — и это честная часть истории: найти причину и починить её — два разных этапа.

 

3. Галочка

Оператор загружал штрихкоды из файла. Одна неотмеченная галочка — и файл получил имя без нужного префикса, а обработка ушла в другую ветку: ту, которая ожидала, что штрихкод уже есть в базе. Штрихкода в базе не было.

Дальше — код в стиле «Пока НЕ Успех Цикл»: попробовать, если не вышло — попробовать ещё. Такая конструкция рассчитана на конфликт блокировок, который рассосётся сам через секунду-другую. Но при ошибке данных операция падала одинаково на каждой итерации, «Успех» не наступал никогда, и система решила ждать, пока штрихкод появится сам. Штрихкод не появился. Система ждала 26 минут.

Самое интересное: тот же паттерн «крутись, пока не получится» был размножен по всему контуру маркировки — печать этикеток, обработка терминалов сбора данных, эмиссия кодов. Восемнадцать таких циклов в шести модулях.

Загрузку штрихкодов исправили в тот же день: лимит попыток и проверка данных до входа в транзакцию. Обработку терминалов переписали. Остальные циклы ждут своей очереди — лечатся они одинаково.

 

4. Воскресный призрак

Отдельная история — про болезнь, которая возвращалась. Один из тяжёлых участков проведения документов казначейства (полтора миллиарда чтений на один документ, 17–27 минут на запись) вылечили точной статистикой: сервер увидел реальные размеры таблиц, выбрал правильный план и стал справляться за секунды. Победа, все довольны.

Через несколько дней — всё вернулось один в один. Будто ничего не чинили.

Разгадка нашлась не сразу. В системе тихо жило регламентное задание, которое каждое воскресенье в 07:00 перестраивало статистику по всей базе — но не подробно, а «на глаз», выборкой в 2,3% от объёма таблицы. По времени совпало до секунды: наша точная статистика — в четверг, задание — в воскресенье в 07:04, а к середине следующей недели казначейство снова проводило документы по полчаса. Как призрак замка: приходит в один и тот же час, всё ломает и уходит, а утром никто не понимает, почему опять холодно.

Таких заданий по статистике на одну базу оказалось три, и они мешали друг другу. Лишнее отключили, нужное сделали не «на глаз», а полным пересчётом с закреплением — чтобы никакой призрак её больше не затирал.

 

5. Кладбище протоколов на 300 гигабайт

Ну и на десерт: файлы никогда не удалялись.

Каждый документ ветеринарного госконтроля — это протокол обмена: тело запроса и тело ответа. Их копилось годами: больше 43 миллионов записей, около 180 гигабайт места в базе (по размерам самих файлов — около 600). Нужны они разве что для разборов с госорганом за прошлые периоды, но исправно нагружали сервер: по этой таблице четыре раза в сутки пересчитывалась статистика полным сканом, по 51 минуте за раз. Три с половиной часа в день на перечитывание протоколов, которые никто никогда не откроет.

Отдельный вопрос — где они лежали. В настройках хранения файлов стоял режим «в информационной базе». То есть файлы хранились прямо внутри SQL Server, в таблицах, среди остатков и проводок, — всего около 300 гигабайт вместе с прочими присоединёнными файлами. Хранить документы в СУБД можно, платформа позволяет. Так же, как можно хранить дрова в холодильнике: технически влезает, но холодильник не для этого, и открывать его становится всё тяжелее.

Перенос в тома на диске — штатная возможность платформы и минус 300 гигабайт из базы без вмешательства в учётные данные. Правда, на таком объёме штатная обработка переноса падала по памяти, и переносить пришлось бы порциями, почти две недели в один поток. Мы отложили это до решения по свёртке: переносить одни и те же файлы дважды смысла нет.

Для полноты картины — коды маркировки: около 220 миллионов записей в справочнике и примерно столько же в регистрах. В пуле кодов около 80% — мёртвый груз, который можно удалять.

Мы видели такое не раз: у каждого журнала есть настройка «хранить N дней», у каждого файла — «где хранить», и почти никто не знает, что они есть.

 

Вместо вывода

Все пять историй — об одном: сбой видно сразу, а причину — только после замеров. И найти причину и починить её — два разных этапа: часть исправлений сделана в тот же день, часть ещё ждёт своей очереди.

Финал — в части 4: как догрузка свёрнутой копии роняла сервер восемнадцать раз за воскресенье, почему повисли полторы тысячи кодов маркировки, как одно подчёркивание замедлило печать до нескольких кодов в минуту — и честная таблица «было / стало».

Случай обезличен, отдельные детали обобщены. Оценки — мнение автора по результатам замеров, а не оценка свёртки как метода или исполнителей в целом.


Технические подробности для коллег

Падения по памяти. Рабочий процесс кластера падал с превышением памяти; в нём одновременно жило около 2 000 фоновых заданий, поэтому каждое падение уносило всё сразу. Журнал запросов к системе маркировки накапливался в одном файле и в конце обработки читался целиком — 64–144 ГиБ за вызов. Отключение этого логирования сняло падения по памяти. Оповещения о ходе работы на каждый код при печати и эмиссии дают не падения, а ожидания: 10 000 кодов — 10 000 вызовов; предложено сообщать раз в 100.

Документ, который ждал сам себя. Профиль проведения выпуска по технологическому журналу: 258 с, из них CPU 45 с, остальное — ожидание. Проведение в своей транзакции перепроводит цепочку связанных документов и держит блокировку очереди фоновых заданий производства; порождённые задания упираются в неё и уходят в TTIMEOUT через 20 с, после чего транзакция откатывается («в данной транзакции уже происходили ошибки»). Целевое решение — штатный пакетный режим формирования и вынос перепроведения цепочки в фоновое задание вне транзакции проведения.

«Пока НЕ Успех Цикл». Конструкция повторяет операцию до успеха без различения ошибок: конфликт блокировки и ошибка данных обрабатываются одинаково. Правило: лимит попыток, повтор только для конфликта блокировок, проверка данных до начала транзакции. В контуре маркировки найдено 18 таких циклов в 6 модулях.

Воскресный призрак. Еженедельное задание sp_updatestats в воскресенье 07:00 пересчитывало статистику выборкой (на ключевом регистре — 2,3% строк) и затирало ранее сделанный FULLSCAN. Лечение: UPDATE STATISTICS … WITH FULLSCAN, PERSIST_SAMPLE_PERCENT = ON — закреплённая выборка сохраняется при последующих пересчётах; лишние задания статистики отключены, оставшееся обслуживание не понижает закреплённые 100%. Проверка: sys.dm_db_stats_properties — сравнить rows_sampled с rows и посмотреть persisted_sample_percent.

Файлы в базе. Режим хранения файлов «в информационной базе» складывает тела файлов в таблицы СУБД. Таблица протоколов госконтроля попадала в пересчёт статистики полным сканом четыре раза в сутки (по 51 мин). Перенос в тома — штатная обработка, но на сотнях гигабайт её стоит запускать порциями: в один заход она упиралась в память.

Вступайте в нашу телеграмм-группу Инфостарт

1С:ERP производительность MS SQL Server статистика блокировки маркировка технологический журнал свертка базы

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

HighLoad оптимизация Разработчик 1С 8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Использование оператора «В» для полей или данных составного типа (например, Регистратор) может приводить к неочевидным проблемам.

10.11.2025    15883    ivanov660    48    

58

HighLoad оптимизация Разработчик 1С:Предприятие 8 1C:ERP Бесплатно (free)

Приведем примеры использования различных в динамических списках и посмотрим, почему это плохо.

18.02.2025    16490    ivanov660    39    

62

HighLoad оптимизация Разработчик Россия Бесплатно (free)

А вы знали, что сервер 1С при соединении с базой на сервере PostgreSQL самостоятельно устанавливает некоторые параметры? Это важно знать при настройке сервера и отладке долгих запросов. Предлагаю разобраться.

27.08.2024    10400    soulner    10    

41

HighLoad оптимизация Технологический журнал Системный администратор Разработчик Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    19125    ivanov660    13    

64

HighLoad оптимизация Разработчик 1С:Предприятие 8 Бесплатно (free)

Метод очень медленно работает, когда параметр приемник содержит намного меньше свойств, чем источник.

06.06.2024    24976    Evg-Lylyk    73    

46

HighLoad оптимизация Разработчик 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    14615    spyke    29    

54
Для отправки сообщения требуется регистрация/авторизация