Один сервер, много баз
Сопровождение этой сети мы ведём с апреля 2025 года: 11 боевых баз в трёх странах, розница и ERP. Самый громкий проект за это время - обрезка главной базы с 4,2 ТБ до 105 ГБ, о нём отдельный кейс. Здесь история тише и полезнее для большинства компаний, потому что общий сервер СУБД есть почти у всех.
На боевом SQL-сервере сети жили кассовая база, учётная ERP, вторая розничная база и ещё несколько баз группы. Сорок восемь ядер, шесть узлов NUMA по восемь. Базы разные, а tempdb, процессор, память и диск на всех одни. Отсюда главное правило, которое мы вынесли из этой работы: когда тормозят кассы, смотреть надо на весь сервер, а не на базу касс.
23 июня: вечерний замер, и блокировки ни при чём
Первым был вечерний замер. С девяти до одиннадцати, в окно закрытия смен, мы снимали картину ожиданий только по кассовой базе: срез каждые 20 секунд, только чтение.
Из 880 замеров активных запросов 583, то есть 66 %, ждали синхронизации параллельных потоков (CXPACKET). Реально работали 188. Ни один замер не показал ожидания на блокировке. Причина лежала в двух заводских настройках сервера: порог параллелизма 5 отправлял в параллель почти любой запрос, а MAXDOP = 0 разрешал одному запросу занять все 48 ядер через границы NUMA-узлов.
Разбор этой части с чек-листом “блокировки или параллелизм” мы опубликовали отдельно: почему в час пик кассы встают. Рекомендацию подготовили сразу после замера: порог 50, MAXDOP 8 по числу ядер в узле. Применяется без перезапуска, откат за секунды.
1 июля: чек проводится двадцать минут
Через восемь дней пришёл инцидент: проведение чека в рознице висело 20 минут. Розничная база при этом была чистой, взаимных блокировок в ней не нашлось. Нашлось другое.
В учётной ERP на том же сервере висела транзакция, открытая около часа и державшая около 56 000 блокировок. Она раздула общую tempdb. Одновременно тяжёлые запросы учётной базы по остаткам и скидкам захватывали ядра, а при заводских настройках даже проведение чека строило параллельный план и вставало в очередь вместе с ними. Кассу душил сосед.
Сделали две вещи в тот же день. Транзакцию сняли. Настройки параллелизма из вечернего аудита применили без перезапуска сервера. Ожидания CXPACKET упали примерно в семь раз, проведение чеков ушло от параллельных планов, кассы заработали штатно.
2 июля: статистике три дня, а она уже врёт
Следующим шагом разобрались, почему учётная база гоняет такие тяжёлые запросы. Статистику в ней последний раз обновляли 29 июня, всего тремя днями раньше. За эти три дня на горячих таблицах изменилось до 39 % строк, и оптимизатор строил планы по картине, которой уже не было.
Обновили статистику по семи таблицам в утреннее окно, с 08:05 до 08:53, задолго до открытия магазинов: вместе 47,8 минуты, размер базы не изменился. Из этого окна вышло практическое правило по режиму сбора:
| Таблица | Режим | Время |
|---|---|---|
| регистр скидок, 45,7 ГБ вместе с индексами | полный просмотр | 29 минут |
| бухгалтерский регистр, 121,5 млн строк | выборка | 8,9 секунды |
Полный просмотр упирается в диск и на гигантах съедает окно целиком. Для самых больших таблиц берём выборку, полный просмотр оставляем точечно для таблиц, где план действительно ошибался.
Там же нашли недостающие индексы, в том числе на регистре скидок, который аудит 21 июня поймал на 405 млн чтений с плохим планом. Ставить их днём не стали. Набор тянул на 10-15 ГБ, а у одной из таблиц уже было девять индексов, так что каждый новый надо проверить на дубли и ставить в режиме ONLINE. Это ушло в ночное окно отдельной задачей.
4-5 июля: отчёты, которые висели по полсуток
Мониторинг показал уже вторую базу. В соседней розничной базе тяжёлые товарные отчёты (остатки, продажи и цены в разрезе номенклатуры, сезона и типа, поверх ограничения прав) застревали в параллельных планах и копились. 4 июля на сервере висели три таких отчёта, каждый по 13-14,5 часа.
Корень тот же, что в учётной базе: статистику обновляли только там, а про соседнюю розницу никто не вспомнил. Обновили за 35,7 минуты, полным просмотром для таблиц меньше 100 млн строк и выборкой для гиганта на 220 млн. Застрявшие отчёты сняли, следующие запуски пошли по нормальному плану.
Транзакции, которые зависают сами
Зависшая транзакция в учётной базе повторялась: четыре раза за несколько дней, каждый раз с новым номером сеанса. Последний запрос у всех был один и тот же, к справочнику видов запасов при проведении, и напрашивался вывод “виноват код”.
Проверили данными. Устаревших и дублирующих видов запасов в базе ноль, значит механизм, на который падало подозрение, отрабатывает вхолостую и быстро. Код оказался типовым, строка в строку одинаковым в трёх ERP-базах сети, и трогать его мы не стали: правка типового кода осложняет каждое следующее обновление. Настоящая причина лежала в инфраструктуре: сеансы проведения обрывались, клиент зависал, а транзакция успевала записать движения и не доходила до фиксации.
Решение разделили на две части. Симптом снимает скрипт, который находит и завершает зависшие транзакции. Корень ищем по консоли кластера 1С: какие сеансы бросаются и почему. Отдельно записали латентный риск: если кто-то пометит вид запасов устаревшим, каждое проведение станет тяжёлым, и закрывается он организационным правилом: коду тут делать нечего.
Что осталось открытым
Недостающие индексы учётной базы ждут ночного окна. Причина обрывов сеансов проведения разбирается по консоли кластера. Стратегическая рекомендация заказчику осталась открытой: учётная аналитика и кассы на одном сервере будут конкурировать всегда, и их стоит разнести по разным экземплярам SQL Server или хотя бы по пулам ресурсов, если редакция сервера это позволяет.
Сопровождение целиком
Обслуживание сервера - одна строка из 39 задач и направлений за 15 месяцев. Среди остальных такие, что обычно всплывают внезапно: журналы регистрации выросли до ~400 ГБ и переехали на отдельный диск, из журнала действий кассира на 21 млн записей удалили ~17,8 млн старше шести месяцев, а при переходе Казахстана на НДС 16 % оказалось, что новой ставки в перечислении конфигурации нет, и все казахстанские базы пришлось обновить структурно.
Как мы ставим регламент обслуживания на MS SQL и PostgreSQL и сколько это стоит - на странице обслуживания баз 1С. Статистика и индексы разобраны по шагам в статье о регламентном обслуживании СУБД.