· 15 мин чтения

Мониторинг MS SQL Server для 1С и учётных систем: ключевые счётчики и готовый шаблон Zabbix

Заявка от клиента звучит всегда одинаково: «1С тормозит, сделайте что-нибудь». В девяти случаях из десяти проблема не в конфигурации и не в коде — упёрлась подсистема MS SQL Server: не хватает памяти под буферный пул, диск не успевает отдавать страницы, или tempdb захлёбывается во временных таблицах. Показываю, на какие счётчики и DMV мы смотрим первыми, какие пороги считаем тревожными и как за один вечер разворачиваем это в Zabbix, чтобы не бегать с DBCC вручную при каждой жалобе.

Почему разбор всегда начинается с SQL Server, а не с конфигурации 1С

У нас на сопровождении десятки баз 1С:Предприятие 8.3 в клиент-серверном варианте — от «Бухгалтерии» на 5 пользователей до УТ/ЗУП на 40–50 рабочих мест. Платформа почти везде 8.3.20–8.3.27, СУБД — MS SQL Server 2016, 2019 или 2022 (Standard Edition, реже Web Edition на совсем небольших конфигурациях). Когда приходит жалоба «стало тормозить», первый вопрос, который мы себе задаём, — не «что там в конфигурации поменяли», а «куда упёрся сервер БД»: в память, в диск или в конкурентный доступ.

Причина в архитектуре 1С: тонкий или толстый клиент формирует запрос, платформа превращает его в T-SQL, а дальше вся тяжесть — на СУБД. Если у SQL Server не хватает оперативной памяти под буферный пул, каждый повторный запрос читает данные заново с диска. Если диск под базой или под tempdb не тянет по IOPS и латентности, любая операция с временными таблицами (а 1С генерирует их массово — виртуальные таблицы регистров, временные таблицы СКД) начинает залипать на PAGEIOLATCH. Пользователь при этом видит только зависшую форму и жалуется на «1С», хотя конфигурация тут ни при чём.

Дальше — конкретные счётчики, которые мы снимаем на диагностике, пороги, которые считаем тревожными по опыту (там, где это не прямая рекомендация Microsoft, помечаю отдельно), и готовый шаблон для Zabbix, который разворачиваем клиенту, чтобы не приезжать на диагностику руками каждый раз.

Память и буферный пул: где на самом деле «тормозит 1С»

Первое, что проверяем, — не хватает ли SQL Server оперативной памяти. Смотрим счётчики объекта SQLServer:Memory Manager и SQLServer:Buffer Manager (доступны и через Perfmon, и через DMV sys.dm_os_performance_counters).

Отдельно проверяем настройку max server memory (MB) в свойствах сервера — на терминальных серверах, где на одной машине крутится ещё и сама 1С, RDS-сессии или файловый сервер, дефолтный «неограниченный» лимит SQL Server регулярно душит остальные службы по памяти. Мы всегда выставляем явный лимит, оставляя операционной системе и остальным сервисам не менее 20–25% RAM, а на серверах с NUMA — считаем отдельно на узел через SQL Server:Buffer Node.

Счётчик / источникЧто показываетПорог, на который ориентируемся
SQLServer:Buffer Manager \ Page life expectancyСреднее время жизни страницы в буферном пуле, сек.<300 сек — официальный порог MS; для серверов >16 ГБ используем формулу (ГБ/4)×300 (оценка по практике)
SQLServer:Memory Manager \ Total Server Memory (KB)Память, фактически занятая под буферный пулСтабильно ≈ Target Server Memory и ≈ max server memory — сигнал «упёрлись в потолок»
SQLServer:Buffer Manager \ Buffer cache hit ratioДоля чтений из кэша, а не с диска<95% на рабочей нагрузке — оценка по практике, повод разбираться
sys.dm_os_process_memory (physical_memory_in_use_kb)Реальное потребление процесса sqlservr.exeСверяем с max server memory и физической RAM хоста

Диск: латентность важнее, чем «сколько всего IOPS»

Второй блок — подсистема хранения. Здесь мы смотрим не абсолютные IOPS (они у всех разные — HDD RAID, SSD, NVMe, виртуальный диск на гипервизоре), а именно латентность отклика, потому что 1С крайне чувствительна к задержкам на операциях с журналом транзакций и с tempdb.

Дальше — что даёт понять, ждёт ли сервер именно диск. Смотрим агрегированную статистику ожиданий:

SELECT wait_type, wait_time_ms, waiting_tasks_count FROM sys.dm_os_wait_stats WHERE wait_type IN ('PAGEIOLATCH_SH','PAGEIOLATCH_EX','WRITELOG','ASYNC_IO_COMPLETION') ORDER BY wait_time_ms DESC;

По документации Microsoft, если средние ожидания PAGEIOLATCH стабильно выше 10 мс — подсистема ввода-вывода под давлением: либо не хватает IOPS, либо диск физически не тот класс, что нужен под нагрузку. Ожидание WRITELOG отдельно указывает на журнал транзакций — часто это RAID-контроллер без battery-backed write cache или журнал, лежащий на том же массиве, что и файлы данных. Один из типовых P0-фиксов у нас на выезде — просто развести .mdf и .ldf по разным физическим томам, и жалобы на «тормозит проведение документов» снимаются без единого изменения в 1С.

CPU и параллелизм: когда тормозит не диск, а сам план запроса

Третий частый сценарий — SQL Server упирается не в диск и не в память, а в CPU из-за неудачно распараллеленных запросов. 1С генерирует немало тяжёлых аналитических запросов (отчёты, СКД, закрытие месяца), и на многоядерных серверах SQL Server может «раздувать» план на десятки потоков там, где выгоднее было бы выполнить его последовательно.

Диагностируем текущую нагрузку по CPU без сторонних утилит через sys.dm_exec_requests и sys.dm_exec_sessions — в паре с sys.dm_exec_sql_text это даёт список самых тяжёлых сейчас запросов с указанием конкретной сессии 1С (по host_process_id и program_name обычно видно, чей это клиентский процесс).

Блокировки и конкурентный доступ: когда «зависла» одна операция, а не весь сервер

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

tempdb: самое частое узкое место в базах 1С, которое не видно из интерфейса программы

tempdb в 1С работает на порядок интенсивнее, чем в среднем OLTP-приложении: временные таблицы для виртуальных таблиц регистров, промежуточные результаты СКД, версии строк при включённом RCSI (см. предыдущий раздел) — всё это уходит именно туда. Если tempdb сконфигурирован «по умолчанию, одним файлом», то на нагруженной базе это стабильно узкое место.

Что проверяем и приводим в порядок:

Короткий скрипт, которым проверяем текущее число файлов и их размер перед выездом к клиенту:

SELECT name, physical_name, size/128 AS size_mb, growth FROM tempdb.sys.database_files;

Готовый шаблон в Zabbix: как мы это автоматизируем у клиента

Ручной прогон DMV на диагностике — это разовая история. Чтобы не приезжать каждый раз, когда «опять тормозит», мы разворачиваем клиенту постоянный мониторинг на Zabbix — благо у большинства уже стоит Zabbix Server для мониторинга инфраструктуры (см. наш опыт с Zabbix 7.0 на других проектах), и добавить туда MS SQL — вопрос одного вечера.

Официальный путь — плагин MSSQL для Zabbix agent 2 (входит в поставку начиная с Zabbix agent 2 версии 6.0) и типовой шаблон «Microsoft SQL Server by Zabbix agent 2» из официального репозитория. Плагин подключается к SQL Server напрямую по протоколу TDS (порт 1433 по умолчанию), поэтому дополнительный ODBC-драйвер на сервере агента не требуется — только сетевая доступность и учётная запись SQL с правами VIEW SERVER STATE.

Шаги внедрения, которые мы повторяем у каждого клиента:

  1. Заводим отдельного SQL-логина только для мониторинга (не sa!) и даём ему GRANT VIEW SERVER STATE TO [zbx_monitor] — этого достаточно для чтения всех нужных DMV, права на изменение данных не нужны;
  2. Устанавливаем/обновляем Zabbix agent 2 на сервере СУБД (или рядом, если агент стоит на другом хосте с сетевым доступом к 1433 порту);
  3. Прописываем сессию подключения в конфиге агента;
  4. Импортируем в Zabbix Server шаблон Microsoft SQL Server by Zabbix agent 2, привязываем к узлу сети, назначаем макрос с именем сессии;
  5. Донастраиваем пороги триггеров под конкретного клиента — дефолтные значения шаблона рассчитаны на «типовой» сервер, для терминалок с 1С мы всегда правим их под пороги из таблиц выше (PLE, латентность диска, RESOURCE_SEMAPHORE).

Фрагмент конфигурации агента (zabbix_agent2.conf или отдельный .d-файл плагина):

Plugins.MSSQL.Sessions.MAIN1C.Uri=sqlserver://SQLSRV01:1433 Plugins.MSSQL.Sessions.MAIN1C.User=zbx_monitor Plugins.MSSQL.Sessions.MAIN1C.Password=<пароль_из_секрет-хранилища>

Быстрая проверка, что плагин вообще видит сервер, без ожидания опроса по расписанию:

zabbix_get -s 127.0.0.1 -k mssql.ping[MAIN1C]

Группа items в шаблонеЧто мониторимНаш триггер (клиентский профиль 1С)
Instance discoveryАвтообнаружение баз данных и job-ов SQL Agent на инстансеИнформационно, база для остальных LLD-правил
Performance counters (Buffer Manager)Page life expectancy, buffer cache hit ratioPLE ниже расчётного порога 15+ минут подряд — Warning; ниже 300 сек — Average
Memory ManagerTotal/Target Server Memory, Memory Grants PendingMemory Grants Pending > 0 дольше 5 минут — Average
Database statusСостояние БД (ONLINE/RESTORING и т.д.), размер файла логаСтатус ≠ ONLINE — Disaster (немедленно)
Backup discoveryВремя последнего успешного backup по каждой базеПолный backup давностью > 26 часов — Average (у 1С обычно ночной full + журнальные)
Job discovery (SQL Agent)Статус последнего выполнения job-ов обслуживания (реиндексация, backup)Последний запуск job = Failed — High

Отдельно на уровне ОС держим классический шаблон Windows by Zabbix agent (или Linux-аналог для SQL Server на Linux) для диска и памяти хоста — латентность и очередь диска технически относятся к ОС, а не к плагину MSSQL, и без них шаблон MSSQL показывает только «внутреннюю» картину сервера БД, без физического диска под ней.

Как читать дашборд целиком, а не по одному счётчику

Главная ошибка, которую мы видим у клиентов, которые пытались настроить мониторинг сами, — реакция на один сработавший триггер без контекста. PLE ниже порога сам по себе не диагноз: если это произошло сразу после ночной реиндексации или после рестарта службы SQL Server, это ожидаемое и временное поведение — буферный пул просто прогревается заново.

Наш порядок разбора инцидента в Zabbix (проверка сверху вниз, по убыванию вероятной причины):

  1. Смотрим триггеры уровня Database status и Backup — если база не ONLINE или backup давно не проходил, это приоритет №1, к производительности отношения не имеющий, но критичный сам по себе;
  2. Смотрим Memory Grants Pending и PLE в связке — если оба «красные» одновременно и держатся не первый час, это память, идём разбираться в раздел про буферный пул;
  3. Проверяем графики диска на уровне ОС (латентность + очередь) за тот же промежуток времени — если они тоже поднялись, то первопричина в диске, а память лишь следствие (SQL Server агрессивнее держится за страницы, потому что подкачка с диска медленная);
  4. Если ни память, ни диск не показывают отклонений, а жалобы всё равно есть — смотрим CPU и RESOURCE_SEMAPHORE/CXPACKET, это, скорее всего, конкретный тяжёлый отчёт или неудачный план запроса, а не системная деградация.

Такой порядок разбора мы фиксируем прямо в описании triggers в Zabbix (поле Description), чтобы дежурный инженер, увидевший алерт ночью, сразу понимал, в какую сторону копать, не поднимая нас по телефону среди ночи по каждому чиху.

Что это даёт на практике: конкретный пример из нашего сопровождения

На одном из клиентских серверов (терминальный сервер + SQL Server 2019 Standard на одной машине, база УТ 11 на 30+ РМ) жалобы «зависает при закрытии месяца» шли из месяца в месяц, и каждый раз списывались на «тяжёлую операцию, надо подождать». После разворачивания описанного мониторинга картина за первую же неделю стала прозрачной: PLE регулярно проваливался в момент ночного backup — полная резервная копия писалась на тот же физический том, где лежали файлы данных, и вытесняла буферный пул. Отдельно ожидания WRITELOG в это же окно подскакивали кратно — журнал транзакций был на том же диске.

Решение оказалось не в «добавить памяти» и не в «оптимизировать 1С», а в разнесении файлов: .ldf перенесли на отдельный SSD-том, окно backup сдвинули на менее нагруженное время и добавили сжатие backup средствами SQL Server, чтобы сократить время самой операции записи. После этого жалобы на закрытие месяца прекратились полностью, а метрики PLE и WRITELOG в Zabbix стали ровной линией без ночных провалов — именно эти графики мы и показываем клиенту как подтверждение, что проблема закрыта, а не «вроде стало лучше на слух».

Частые вопросы

Обязательно ли ставить ODBC-драйвер SQL Server, чтобы мониторить его через Zabbix?
Нет, если используете официальный плагин MSSQL для Zabbix agent 2 — он общается с сервером напрямую по протоколу TDS (тот же порт 1433, что и клиентские подключения 1С), отдельный ODBC-драйвер не требуется. ODBC нужен только если вы собираете метрики альтернативным способом через odbc.get и самописные шаблоны.
Почему Page Life Expectancy иногда падает даже на здоровом сервере?
Кратковременное падение PLE — ожидаемое поведение сразу после рестарта службы SQL Server, после ночной реиндексации/обновления статистики или сразу после резервного копирования, которое вытесняет часть буферного пула. Тревожный сигнал — не разовое падение, а устойчиво низкое значение в течение рабочего дня под обычной нагрузкой.
Нужно ли клиенту с 1С в файловом варианте (без сервера СУБД) что-то из этого мониторинга?
Нет, всё описанное относится к клиент-серверному варианту 1С:Предприятие с MS SQL Server. Файловая база (.1CD) работает без отдельной СУБД, и там симптомы медленной работы почти всегда связаны с сетевым диском, антивирусом или самим файлом базы, а не со счётчиками SQL Server.
Сколько занимает внедрение такого мониторинга у клиента, если Zabbix Server уже стоит?
По нашей практике — один визит: заведение SQL-логина для мониторинга с правом VIEW SERVER STATE, установка/обновление Zabbix agent 2, настройка сессии подключения к MSSQL-плагину и импорт официального шаблона с донастройкой порогов под конкретный сервер укладываются в несколько часов работы.
Что делать, если RESOURCE_SEMAPHORE регулярно в топе ожиданий, а памяти на сервере вроде достаточно?
Это ожидание указывает не на нехватку памяти вообще, а на нехватку memory grant под конкретный тяжёлый запрос (обычно сортировки или хэш-соединения в отчётах). Сначала находим сам запрос через sys.dm_exec_requests и sys.dm_exec_query_stats, и часто решение — переписать отчёт или обновить статистику, а не увеличивать max server memory.
📄
Скачайте подробный разбор в PDF Кейсы, статистика, типовые ошибки и чек-лист самопроверки — 12 страниц
Скачать PDF

Подпишитесь на разборы ITfresh

Раз в неделю — практичные материалы по ИТ для бизнеса: без спама, только польза.