Почему SQL Server занимает всю оперативную память на новом сервере 1С и почему система может работать медленнее

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

После переноса системы 1С:Предприятие с обычного процессора Core i7 на новый сервер с Xeon, большим количеством ядер и увеличенным объемом оперативной памяти администратор нередко видит неожиданную картину: процесс sqlservr.exe постепенно занимает почти всю разрешенную ему память, а работа пользователей при этом не ускоряется или даже становится медленнее. На старом сервере значительную часть памяти могли занимать процессы rphost.exe, а на новом основным потребителем становится SQL Server.

Первое, что важно исправить в понимании ситуации: стремление SQL Server занять память до значения max server memory является штатным поведением. СУБД использует память для буферного пула, кэша планов выполнения, служебных структур и выполнения запросов. Наличие большого объема памяти у процесса sqlservr.exe само по себе не является утечкой и не доказывает, что именно память стала причиной замедления.

Проблема начинается тогда, когда из-за слишком высокого лимита памяти операционная система, процессы 1С, антивирус, агенты резервного копирования или другие службы испытывают реальный дефицит памяти, либо когда после переноса изменились планы запросов, топология процессоров, настройки параллелизма, скорость одного ядра, производительность дисковой подсистемы или конфигурация tempdb.

Главный вывод: высокая память SQL Server и низкая производительность не обязательно связаны напрямую

Заполненный буферный пул чаще является нормой, а не неисправностью. Если данные уже прочитаны с диска, SQL Server старается сохранить их в памяти для повторного использования. Он не обязан освобождать кэш только ради того, чтобы в диспетчере задач отображалось больше свободной памяти.

При этом параметр max server memory ограничивает не абсолютно все выделения процесса sqlservr.exe. Часть памяти используется за пределами области, непосредственно управляемой этим параметром: например, стеки рабочих потоков, некоторые буферы резервного копирования, компоненты расширений и внешние провайдеры. Поэтому рабочий набор процесса иногда может быть больше установленного значения max server memory.

Сравнивать только размеры процессов sqlservr.exe и rphost.exe недостаточно. На разных серверах одинаковая информационная база может формировать другой кэш, другие планы выполнения и другое распределение работы между сервером приложений и СУБД. Для диагностики нужно смотреть не только занятую память, но и ожидания, загрузку процессора, задержки дисков, блокировки, планы запросов и наличие давления памяти.

Почему новый Xeon может оказаться медленнее старого Core i7

Количество ядер и общий объем оперативной памяти не гарантируют ускорение конкретной нагрузки 1С. Для интерактивной работы часто важны задержка выполнения коротких запросов и производительность одного ядра, а не только суммарная вычислительная мощность.

  1. Ниже производительность одного ядра. Серверный процессор может иметь больше ядер, каналов памяти и линий ввода-вывода, но работать на меньшей частоте или дольше удерживать низкие частоты. Большое число коротких последовательных операций 1С при этом выполняется медленнее.

  2. Неподходящая схема электропитания. Сбалансированный профиль Windows или энергосберегающие настройки BIOS могут задерживать переход процессора на высокую частоту. Для нагруженного сервера обычно проверяют профиль высокой производительности, настройки управления частотой и фактические частоты под нагрузкой.

  3. Другая топология NUMA. Новый сервер может иметь несколько сокетов, несколько аппаратных узлов NUMA на сокет либо включенные режимы вроде кластеризации ядер. Неправильная установка модулей памяти, несимметричное заполнение каналов или неудачная виртуальная топология способны увеличить задержки доступа к памяти.

  4. Изменившиеся планы запросов. После переноса могут отличаться версия и сборка SQL Server, уровень совместимости базы, оценщик кардинальности, статистика, параметры сервера и содержимое кэша планов. Даже при одинаковой базе это может привести к другим планам выполнения.

  5. Более медленная дисковая подсистема. Новый сервер может иметь быстрый процессор, но медленный RAID-контроллер, кэш записи без защиты, неподходящий размер полосы, общий массив для данных и журналов либо высокие задержки виртуального хранилища.

  6. Отличия в программной среде. На производительность влияют версия платформы 1С, драйвер подключения, накопительные обновления SQL Server, антивирусные исключения, резервное копирование, мониторинг и фоновые задания.

Поэтому версия «новый сервер тормозит только из-за NUMA» слишком упрощает проблему. NUMA нужно проверить, но считать ее причиной без измерений нельзя.

Что такое NUMA и как она действительно влияет на SQL Server

NUMA означает неравномерный доступ к памяти. Процессор быстрее обращается к памяти своего локального узла и медленнее — к памяти другого узла. Такая архитектура типична для многосокетных серверов, но аппарат может представлять несколько узлов и внутри одного сокета. В виртуальной машине топологию NUMA формирует гипервизор.

Windows Server и SQL Server учитывают эту топологию. Начиная с SQL Server 2016, если в аппаратном узле или сокете обнаружено больше восьми физических ядер, ядро СУБД по умолчанию может создать дополнительные узлы soft-NUMA. Их назначение — распределить внутренние структуры и рабочие потоки, улучшив масштабирование на многоядерных системах.

Автоматическую soft-NUMA не следует отключать только потому, что SQL Server использует много памяти. В современных версиях это штатный механизм оптимизации. Отключение имеет смысл лишь после подтвержденной проблемы и сравнительного нагрузочного теста.

Для проверки версии, процессорной топологии и созданных узлов можно выполнить следующие запросы:


SELECT
@@VERSION AS sql_server_version;

SELECT
cpu_count,
scheduler_count,
hyperthread_ratio,
socket_count,
numa_node_count,
softnuma_configuration_desc
FROM sys.dm_os_sys_info;

SELECT
node_id,
node_state_desc,
memory_node_id,
processor_group,
cpu_count,
online_scheduler_count,
idle_scheduler_count,
active_worker_count,
avg_load_balance
FROM sys.dm_os_nodes
WHERE node_state_desc NOT LIKE N'%DAC%'
ORDER BY node_id;

SELECT
scheduler_id,
parent_node_id,
cpu_id,
status,
is_online,
is_idle,
current_tasks_count,
runnable_tasks_count,
current_workers_count
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
ORDER BY parent_node_id, scheduler_id;

Дополнительно необходимо открыть журнал ошибок SQL Server после запуска службы. В нем указываются количество сокетов, физических и логических процессоров, доступные ядра, аппаратные узлы NUMA и факт включения автоматической soft-NUMA.

Если тестирование действительно показало, что автоматическая soft-NUMA ухудшает именно эту нагрузку, в современных версиях ее можно временно отключить следующим образом:

ALTER SERVER CONFIGURATION SET SOFTNUMA OFF;

После изменения требуется перезапуск службы SQL Server. Для возврата штатного поведения используется значение ON. Старые советы с флагами трассировки для управления soft-NUMA нельзя механически переносить на современные версии: например, флаг 8079 относился к SQL Server 2014 SP2, а начиная с SQL Server 2016 этим механизмом управляет само ядро СУБД.

Параллелизм запросов: MAXDOP и cost threshold for parallelism

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

Параметр max degree of parallelism, или MAXDOP, ограничивает количество процессоров, используемых одной параллельной операцией. Значение 0 разрешает использовать все доступные процессоры в пределах внутренних ограничений, а значение 1 запрещает параллельные планы.

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

Текущие значения можно проверить и изменить без перезапуска службы:


SELECT
name,
value,
value_in_use
FROM sys.configurations
WHERE name IN
(
N'max degree of parallelism',
N'cost threshold for parallelism',
N'max server memory (MB)',
N'min server memory (MB)'
)
ORDER BY name;

EXEC sys.sp_configure N'show advanced options', 1;
RECONFIGURE;

EXEC sys.sp_configure N'max degree of parallelism', 1;
RECONFIGURE;

EXEC sys.sp_configure N'show advanced options', 0;
RECONFIGURE;

cost threshold for parallelism — это не время выполнения запроса в секундах. Это условная расчетная стоимость последовательного плана, после превышения которой оптимизатор начинает рассматривать параллельные варианты.

Значение по умолчанию 5 является стартовым, а не универсально рекомендуемым. Для современных серверов его нередко увеличивают, чтобы мелкие OLTP-запросы оставались последовательными. Но значения 50, 70 или 100 нельзя назначать вслепую: порог повышают небольшими шагами и оценивают полный рабочий цикл по данным Query Store и статистике ожиданий.

Если установлен MAXDOP = 1, параметр cost threshold for parallelism не влияет на выполнение запросов. Поэтому одновременная рекомендация выставить MAXDOP = 1 и долго подбирать порог параллелизма не имеет практического смысла.

Как определить, есть ли реальный дефицит памяти

Оценивать состояние только по диспетчеру задач нельзя. Нужно проверить доступную память операционной системы, сигналы давления памяти внутри процесса SQL Server и соотношение фактически выделенной и целевой памяти сервера.


SELECT
total_physical_memory_kb / 1024 AS total_physical_memory_mb,
available_physical_memory_kb / 1024 AS available_physical_memory_mb,
total_page_file_kb / 1024 AS total_page_file_mb,
available_page_file_kb / 1024 AS available_page_file_mb,
system_memory_state_desc
FROM sys.dm_os_sys_memory;

SELECT
physical_memory_in_use_kb / 1024 AS sql_process_memory_mb,
locked_page_allocations_kb / 1024 AS locked_pages_mb,
large_page_allocations_kb / 1024 AS large_pages_mb,
memory_utilization_percentage,
available_commit_limit_kb / 1024 AS available_commit_limit_mb,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;

SELECT
committed_kb / 1024 AS total_server_memory_mb,
committed_target_kb / 1024 AS target_server_memory_mb
FROM sys.dm_os_sys_info;

Признаками проблемы являются не просто большие цифры у sqlservr.exe, а сочетание нескольких факторов: мало доступной физической памяти, активный файл подкачки, значения process_physical_memory_low = 1 или process_virtual_memory_low = 1, ошибки нехватки памяти, сильное падение производительности во время роста потребления и вытеснение рабочего набора других процессов.

Если Total Server Memory заметно ниже Target Server Memory уже после прогрева системы и под стабильной нагрузкой, это может указывать на давление памяти внутри SQL Server. Сразу после запуска службы такое различие нормально: СУБД набирает память постепенно.

Как правильно установить max server memory на совмещенном сервере 1С и SQL Server

Универсального правила «выдать SQL Server 70–85 процентов всей памяти» не существует. Такое приближение может подойти выделенному серверу СУБД, но быть опасным на машине, где одновременно работают rphost.exe, сервер администрирования 1С, фоновые задания, антивирус, резервное копирование и другие службы.

Практический начальный расчет для совмещенного сервера выглядит так:


Лимит SQL Server =
физическая память
- резерв операционной системы
- пиковая память процессов 1С
- память остальных служб
- запас на кратковременные пики

Например, при 128 ГБ физической памяти можно предварительно заложить 12 ГБ для Windows, 24 ГБ под подтвержденный пиковый объем rphost.exe, 4 ГБ для прочих служб и 8 ГБ запаса. В этом условном примере начальный лимит SQL Server составит около 80 ГБ, то есть 81920 МБ. Это не готовая рекомендация для любого сервера, а пример расчета, который затем уточняется по мониторингу полной рабочей нагрузки.


EXEC sys.sp_configure N'show advanced options', 1;
RECONFIGURE;

EXEC sys.sp_configure N'max server memory (MB)', 81920;
RECONFIGURE;

EXEC sys.sp_configure N'show advanced options', 0;
RECONFIGURE;

Изменение max server memory применяется без перезапуска службы. Значение min server memory на совмещенном сервере обычно оставляют равным 0, если нет обоснованного сценария резервирования памяти. Устанавливать одинаковые или почти одинаковые значения min server memory и max server memory не рекомендуется.

После изменения лимита следует наблюдать как минимум полный рабочий день, включая массовые операции, проведение документов, закрытие месяца, обмены, резервное копирование и тяжелые отчеты. Если процессы 1С продолжают испытывать давление памяти, лимит SQL Server уменьшают. Если SQL Server постоянно испытывает внутренний дефицит памяти, а у системы остается устойчивый резерв, лимит можно осторожно увеличить.

Lock Pages in Memory: полезная настройка, которая требует осторожности

Право Lock Pages in Memory позволяет SQL Server удерживать значительную часть памяти в физической RAM и снижает риск вытеснения буферного пула в файл подкачки. В современных версиях рекомендуется выдавать это право SID службы Database Engine, а не конкретной учетной записи, чтобы настройка сохранялась при смене сервисного аккаунта.

Однако Lock Pages in Memory не исправляет плохие запросы, неверный MAXDOP или слишком высокий лимит памяти. Если включить блокировку страниц и оставить завышенный max server memory, операционной системе и процессам 1С может стать только хуже. Поэтому сначала задают безопасный лимит, затем включают право и проверяют поведение системы.

После предоставления права требуется перезапуск экземпляра SQL Server. Факт использования заблокированных страниц можно контролировать по полю locked_page_allocations_kb представления sys.dm_os_process_memory и по журналу ошибок.

Instant File Initialization: ускоряет рост файлов, но не лечит потребление памяти

Instant File Initialization позволяет быстрее создавать и увеличивать файлы данных, а также ускоряет некоторые операции восстановления, потому что новые области файла не заполняются нулями перед использованием. Для этого SID или учетной записи службы SQL Server предоставляется право Windows Perform volume maintenance tasks.

Начиная с SQL Server 2022, мгновенная инициализация также может применяться к событиям автоматического увеличения журнала транзакций размером до 64 МБ. Более крупный рост журнала по-прежнему требует обычной инициализации. Эта настройка полезна для стабильности операций с файлами, но не объясняет, почему процесс sqlservr.exe занимает много оперативной памяти.

Проверить состояние можно запросом:


SELECT
servicename,
service_account,
instant_file_initialization_enabled
FROM sys.dm_server_services;

tempdb и устаревшие флаги трассировки

В старых рекомендациях для 1С часто встречаются флаги трассировки 1117 и 1118. Для современных версий SQL Server их нельзя включать механически.

  1. Флаг 1118. Начиная с SQL Server 2016, соответствующее поведение для tempdb используется по умолчанию, а управление смешанными экстентами выполняется параметрами базы. Флаг больше не дает прежнего эффекта.

  2. Флаг 1117. Начиная с SQL Server 2016, рост файлов настраивается параметрами файловой группы. Для tempdb современные версии умеют синхронно увеличивать файлы данных без этого флага.

  3. Флаг 4199. Он включает определенные исправления оптимизатора запросов, выпущенные в обновлениях. В современных версиях часть исправлений уже активируется уровнем совместимости базы, а для остальных существует параметр QUERY_OPTIMIZER_HOTFIXES. Включать 4199 глобально без проверки планов и регрессионного тестирования не следует.

Для tempdb важнее проверить количество и размер файлов данных. В качестве начальной точки Microsoft рекомендует одинаковые по размеру файлы: по одному на логический процессор, но не более восьми на первом этапе. Если подтверждено ожидание на страницах распределения PAGELATCH, файлы добавляют группами и снова измеряют результат.


SELECT
file_id,
name,
type_desc,
size * 8 / 1024 AS size_mb,
growth,
is_percent_growth,
physical_name
FROM tempdb.sys.database_files
ORDER BY type_desc, file_id;

Файлы данных tempdb должны иметь одинаковый начальный размер и одинаковый прирост в мегабайтах, а не в процентах. Добавление большого количества файлов без подтвержденной конкуренции также не является универсальным способом ускорения.

Обновления, уровень совместимости, статистика и планы выполнения

После миграции необходимо сравнить не только настройки экземпляра, но и программные версии. Устаревшая сборка SQL Server может содержать уже исправленные ошибки масштабирования, планировщика, памяти или tempdb. На сервер следует устанавливать актуальное накопительное обновление, предварительно проверенное на тестовой среде.

Нужно проверить уровень совместимости каждой базы:


SELECT
name,
compatibility_level
FROM sys.databases
WHERE database_id > 4
ORDER BY name;

Повышение уровня совместимости может включить новый оценщик кардинальности и интеллектуальную обработку запросов, но одновременно изменить планы. Поэтому уровень не меняют вслепую: сначала включают Query Store, фиксируют базовую производительность и анализируют регрессии.

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

Что проверить вместо попыток угадать причину

Для расследования нужно собрать данные в момент замедления, а не только после него.

  1. Ожидания SQL Server. Они показывают, где запросы теряют время: процессор, диски, блокировки, параллелизм, память, сеть или tempdb.

  2. Query Store. Позволяет найти запросы с ухудшившимися планами, ростом длительности, чтений или потребления процессора после миграции.

  3. Технологический журнал 1С. Нужен для сопоставления медленных серверных вызовов с конкретными запросами и операциями пользователей.

  4. Счетчики Windows. Следует контролировать доступную память, файл подкачки, очереди процессора, частоты CPU, задержки чтения и записи, длину дисковых очередей и сетевые задержки.

  5. Блокировки и взаимоблокировки. Быстрый процессор не устраняет конкуренцию за одни и те же данные. После переноса более высокая параллельность пользователей может даже усилить блокировки.

Для первичного просмотра накопленных ожиданий можно использовать:


SELECT TOP (30)
wait_type,
waiting_tasks_count,
wait_time_ms,
signal_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN
(
N'BROKER_EVENTHANDLER',
N'BROKER_RECEIVE_WAITFOR',
N'BROKER_TASK_STOP',
N'BROKER_TO_FLUSH',
N'CHECKPOINT_QUEUE',
N'CLR_AUTO_EVENT',
N'CLR_MANUAL_EVENT',
N'DBMIRROR_DBM_EVENT',
N'DBMIRROR_EVENTS_QUEUE',
N'DBMIRROR_WORKER_QUEUE',
N'DIRTY_PAGE_POLL',
N'DISPATCHER_QUEUE_SEMAPHORE',
N'FT_IFTS_SCHEDULER_IDLE_WAIT',
N'HADR_CLUSAPI_CALL',
N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
N'LAZYWRITER_SLEEP',
N'LOGMGR_QUEUE',
N'ONDEMAND_TASK_QUEUE',
N'REQUEST_FOR_DEADLOCK_SEARCH',
N'RESOURCE_QUEUE',
N'SLEEP_TASK',
N'SLEEP_SYSTEMTASK',
N'SQLTRACE_BUFFER_FLUSH',
N'WAITFOR',
N'XE_DISPATCHER_WAIT',
N'XE_TIMER_EVENT'
)
ORDER BY wait_time_ms DESC;

Статистика ожиданий накапливается с момента запуска экземпляра или последнего сброса, поэтому ее нужно сравнивать по интервалам. Само наличие CXPACKET или CXCONSUMER не доказывает неправильный параллелизм: важны доля ожидания, конкретные запросы и фактическая загрузка CPU.

Рекомендуемый порядок действий

  1. Зафиксировать версии Windows Server, платформы 1С, SQL Server, накопительного обновления и уровень совместимости базы.

  2. Проверить профиль электропитания, частоты процессора под нагрузкой, конфигурацию BIOS, заполнение каналов памяти и топологию аппаратной NUMA.

  3. Убедиться, что SQL Server не получил почти всю физическую память на совмещенном сервере. Рассчитать max server memory с учетом реального пика rphost.exe и запаса для Windows.

  4. Для типовой OLTP-нагрузки 1С проверить работу с MAXDOP = 1. Не подбирать cost threshold for parallelism, пока параллелизм полностью отключен.

  5. Не отключать soft-NUMA без доказательств. Сначала изучить журнал ошибок, топологию узлов, распределение планировщиков и результаты нагрузочного теста.

  6. Проверить tempdb: количество одинаковых файлов, размер, прирост, размещение и наличие ожиданий PAGELATCH. Не включать устаревшие флаги 1117 и 1118 на современных версиях.

  7. Включить и использовать Query Store, собрать технологический журнал 1С, ожидания SQL Server и счетчики Windows в момент проблемы.

  8. Проверить задержки файлов данных, журналов и tempdb, а также настройки RAID, кэш контроллера, антивирусные исключения и фоновые задания.

  9. Менять по одному параметру и проводить одинаковый нагрузочный тест. Одновременное изменение памяти, MAXDOP, soft-NUMA, флагов и файлов tempdb не позволит понять, что именно повлияло на результат.

Итог

Когда SQL Server занимает память до установленного лимита, это в большинстве случаев нормальная работа кэша. Настоящая неисправность — не «много памяти у sqlservr.exe», а измеримое давление на операционную систему и процессы 1С, медленные запросы, блокировки, неудачные планы, перегруженные диски или неправильное использование процессоров.

На новом многоядерном сервере прежде всего нужно задать обоснованный max server memory, проверить MAXDOP, топологию NUMA, сборку SQL Server, tempdb, планы запросов и дисковую подсистему. Автоматическая soft-NUMA, флаги трассировки и другие низкоуровневые параметры должны изменяться только после диагностики и сравнительного тестирования.

← На главную