1С и MS SQL Server изнутри: путь запроса, блокировки, обслуживание базы

· 11 мин

Содержание

1С на SQL Server работает по трёхзвенной схеме: пользователь общается только с кластером серверов 1С, а с базой данных говорит рабочий процесс rphost. Он переводит запросы встроенного языка в T-SQL, отправляет их в MS SQL Server и держит транзакции. Поэтому архитектура, блокировки и производительность зависят сразу от двух систем: от настроек кластера 1С и от настроек СУБД.

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

Как устроена связка сервера 1С и SQL Server

В клиент-серверном варианте участвуют три уровня. Клиент (толстый, тонкий или веб) не подключается к SQL Server напрямую. Он видит только кластер 1С.

Путь соединения:

  1. 🖥️ Клиент обращается к агенту сервера ragent — по умолчанию порт 1540.
  2. 🧭 Агент передаёт его менеджеру кластера rmngr — порт 1541.
  3. ⚙️ Менеджер назначает рабочий процесс rphost. Диапазон портов рабочих процессов задаётся в свойствах рабочего сервера, по умолчанию 1560:1591.
  4. 🗄️ Рабочий процесс открывает соединение с SQL Server и выполняет запросы к базе.

Строку подключения к СУБД хранят свойства информационной базы в кластере: сервер баз данных, тип СУБД MSSQLServer, имя базы и пользователь SQL Server. Их видно в консоли администрирования серверов 1С, в свойствах базы.

Где что хранится

ЧтоГде живётЧем управляется
Данные (справочники, документы, регистры)База на SQL ServerSQL Server
Сеансы, соединения, управляемые блокировкиМенеджер кластера 1СКластер 1С
Кэш метаданных, сеансовые данныеРабочие процессы и каталог кластераКластер 1С
КонфигурацияСлужебные таблицы в той же базе SQLПлатформа

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

Во что 1С превращает запросы: таблицы, T-SQL и план выполнения

Платформа не хранит объекты под их именами. Справочник «Номенклатура» в SQL Server — это таблица вида _Reference45, реквизит — колонка _Fld1234. Ссылки хранятся как binary(16) в полях _IDRRef, у объектов есть поле версии _Version, пометка удаления _Marked, у документов — _Posted.

Соответствие имён можно получить из самой 1С функцией ПолучитьСтруктуруХраненияБазыДанных(). Без неё в логах SQL Server не разобраться, какой регистр тормозит.

Структура = ПолучитьСтруктуруХраненияБазыДанных(, Истина);
Для Каждого Строка Из Структура Цикл
    Сообщить(Строка.Метаданные + " = " + Строка.ИмяТаблицыХранения);
КонецЦикла;

Второй параметр Истина возвращает имена в терминах СУБД. Код выполняется на сервере с правами администратора.

Как запрос 1С становится T-SQL

Рабочий процесс транслирует текст запроса в T-SQL. Несколько последствий, которые видны в профилировщике:

  • 📊 Виртуальные таблицы Остатки и ОстаткиИОбороты разворачиваются в подзапросы к таблицам итогов регистров (_AccumRgT…) и к таблице движений. Если параметр периода задан, читаются итоги, а не все движения.
  • 🧮 Временные таблицы ПОМЕСТИТЬ создаются в tempdb как #tt…. Отсюда нагрузка на tempdb в тяжёлых отчётах.
  • 🔁 Запросы уходят параметризованными, SQL Server кэширует их планы и использует повторно.
  • 🔐 Если включены ограничения доступа к данным (RLS), к запросу добавляются условия, и план может заметно усложниться.

Почему план бывает плохим

SQL Server строит план по статистике распределения данных. Статистика устарела — оптимизатор ошибается в числе строк и выбирает сканирование вместо поиска по индексу или неудачный порядок соединений.

Частые причины медленного плана со стороны 1С:

  1. ❌ Отбор по полю, для которого нет индекса. В конфигураторе у реквизита есть свойство «Индексировать».
  2. ❌ Соединение с подзапросом вместо временной таблицы — оптимизатор плохо оценивает подзапросы.
  3. ❌ Отбор по реквизиту через точку («Контрагент.ИНН») — каждое разыменование добавляет соединение.
  4. ❌ Условие на виртуальную таблицу вынесено в ГДЕ, а не в параметры таблицы. Тогда сначала читается весь остаток, потом фильтруется.

Транзакции и блокировки 1С на SQL Server

Запись и проведение документа идут в транзакции. Пока она открыта, изменённые строки заблокированы. От того, кто ставит блокировки, зависит, сколько пользователей могут работать параллельно.

Режимы управления блокировками

Режим задаёт свойство конфигурации «Режим управления блокировкой данных». Значений три: «Автоматический», «Управляемый», «Автоматический и управляемый».

РежимКто блокируетПоследствия
АвтоматическийSQL Server, высокий уровень изоляции транзакцийБлокировки шире нужного, чтение ждёт запись, частые взаимоблокировки
УправляемыйМенеджер блокировок кластера 1С + SQL ServerБлокируются только нужные данные, чтение не ждёт запись
Автоматический и управляемыйЗадаётся у каждого объекта метаданныхПереходный вариант для доработанных старых конфигураций

Типовые конфигурации на 8.3 (Бухгалтерия 3.0, ЗУП 3.1, УТ 11, ERP) работают в управляемом режиме. В этом режиме при работе с SQL Server и режиме совместимости 8.3 платформа использует для базы версионирование строк (READ_COMMITTED_SNAPSHOT). Чтение видит последнюю зафиксированную версию строки и не ждёт пишущую транзакцию.

Код проведения в управляемом режиме сам объявляет, что блокировать, объектом БлокировкаДанных:

Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
Элемент.Режим = РежимБлокировкиДанных.Исключительный;
Элемент.УстановитьЗначение("Склад", Склад);
Блокировка.Заблокировать();

Здесь блокируются остатки только одного склада, а не весь регистр.

Ошибки блокировок и что они значат

  • ⏳ Превышено максимальное время ожидания предоставления блокировки — сработал таймаут управляемой блокировки 1С. Кто-то долго держит те же данные. Ищите длинную транзакцию.
  • 💥 Конфликт блокировок при выполнении транзакции с текстом SQL Server про взаимоблокировку и «жертву» — deadlock: две транзакции ждут друг друга, SQL Server прерывает одну.
  • 🐢 Истекло время ожидания запроса на блокировку от провайдера SQL — ожидание блокировки на уровне СУБД, а не 1С. Типично для автоматического режима или эскалации блокировок.
Диагностика: выберите симптом

Настройка производительности SQL Server под 1С

Настройки по умолчанию у SQL Server рассчитаны на универсальную нагрузку. Для базы 1С с короткими транзакциями и множеством пользователей их стоит поправить.

Память

Параметр max server memory ограничивает буферный пул SQL Server. Без него СУБД со временем займёт почти всю память, и при общем сервере рабочим процессам 1С не хватит места.

Ориентир расчёта: из общего объёма вычесть память под ОС (4–6 ГБ) и под процессы rphost, если они на той же машине. Пример: сервер 64 ГБ, ОС — 4 ГБ, 1С в пике берёт 16 ГБ. Остаётся 64 − 4 − 16 = 44 ГБ для max server memory.

EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'max server memory (MB)', 45056; RECONFIGURE;

45056 МБ — это 44 ГБ (44 × 1024).

Со стороны 1С расход памяти ограничивается в свойствах рабочего сервера: «Критический объём памяти процессов» и «Безопасный расход памяти за один вызов». Они защищают сервер от одного тяжёлого отчёта, который съедает всю память.

Параллелизм

Для 1С обычно рекомендуют max degree of parallelism = 1. Короткие запросы учётной системы не выигрывают от параллельных планов, а ожидания CXPACKET растут.

EXEC sp_configure 'max degree of parallelism', 1; RECONFIGURE;

Если в базе много тяжёлых аналитических отчётов, вместо MAXDOP = 1 можно оставить 2–4 и поднять cost threshold for parallelism до 50 и выше. Тогда параллельно пойдут только действительно тяжёлые запросы.

Диски и tempdb

Что даёт заметный выигрыш:

  • 💾 Файлы данных, журнал транзакций и tempdb — на разных быстрых дисках (SSD или NVMe).
  • 📁 Для tempdb — несколько файлов данных одинакового размера, обычно по числу ядер, но не больше 8.
  • 📏 Автоприращение задавать в мегабайтах (например, 512 МБ), а не в процентах.
  • ⚡ В схеме электропитания Windows выбрать «Высокая производительность».

Модель восстановления

МодельКогда подходитРиски
SimpleПотеря данных за день допустима, бэкап раз в суткиВосстановление только на момент полной копии
FullНужно восстанавливать на любой момент времениЖурнал растёт, если не делать резервные копии журнала

При модели Full без регулярного бэкапа журнала файл .ldf растёт до заполнения диска, после чего база перестаёт принимать изменения.

Регламентное обслуживание базы данных 1С на SQL Server

Без обслуживания база деградирует: индексы фрагментируются, статистика устаревает, планы портятся. Регламент настраивают планами обслуживания SQL Server (Maintenance Plans) или заданиями агента SQL Server на ночное время.

Базовый набор операций:

  1. 🔄 Обновление статистики — ежедневно. Самая полезная операция для 1С.
  2. 🧹 Очистка процедурного кэша — сразу после обновления статистики, чтобы планы перестроились по новым данным.
  3. 🧱 Дефрагментация индексов — раз в неделю: при фрагментации 5–30 % реорганизация, выше 30 % перестроение.
  4. 🩺 Проверка целостности DBCC CHECKDB — раз в неделю.
  5. 💾 Резервное копирование — полная копия ежедневно, при модели Full плюс копии журнала каждые 15–60 минут.
USE [buh];
EXEC sp_updatestats;
DBCC FREEPROCCACHE;

DBCC FREEPROCCACHE очищает кэш планов всего экземпляра SQL Server, а не одной базы. Несколько минут после неё запросы будут работать медленнее, пока планы строятся заново. Запускайте ночью, когда пользователей нет.

Проверить фрагментацию индексов:

SELECT OBJECT_NAME(s.object_id) AS tbl, i.name AS idx,
       s.avg_fragmentation_in_percent, s.page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') s
JOIN sys.indexes i ON i.object_id = s.object_id AND i.index_id = s.index_id
WHERE s.page_count > 1000
ORDER BY s.avg_fragmentation_in_percent DESC;

Маленькие индексы (меньше 1000 страниц) дефрагментировать смысла нет — выигрыша не будет.

Обслуживание со стороны 1С

У регистров накопления и бухгалтерии есть итоги. Их актуальность важна для скорости остатков. Управлять итогами можно через Все функции → Стандартные → Управление итогами: установить период рассчитанных итогов, пересчитать итоги, включить разделение итогов.

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

Не делайте регулярное сжатие базы (SHRINK). Оно фрагментирует индексы, а база всё равно вырастет снова. Сжатие оправдано только разово, после удаления большого объёма данных.

Ночной регламент базы 1С на SQL Server
Выполнено: 0 / 7

Диагностика проблем производительности и анализ логов

Начинайте с вопроса: где время — в 1С или в СУБД? Ответ дают два источника: технологический журнал 1С и динамические представления SQL Server.

Технологический журнал 1С

Журнал включается файлом logcfg.xml в каталоге conf платформы на сервере 1С (например, C:\Program Files\1cv8\conf). Платформа подхватывает изменения файла без перезапуска службы.

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="D:\techlog" history="24">
    <event><eq property="name" value="TLOCK"/></event>
    <event><eq property="name" value="TTIMEOUT"/></event>
    <event><eq property="name" value="TDEADLOCK"/></event>
    <event><eq property="name" value="EXCP"/></event>
    <event>
      <eq property="name" value="DBMSSQL"/>
      <gt property="duration" value="1000000"/>
    </event>
    <property name="all"/>
  </log>
  <plansql/>
</config>

Что ловят события:

  • 🔒 TLOCK — установка управляемых блокировок, TTIMEOUT — таймауты, TDEADLOCK — взаимоблокировки.
  • 🐌 DBMSSQL — запросы к SQL Server. Фильтр по duration оставляет только долгие: в 8.3 длительность измеряется в микросекундах, 1 000 000 — одна секунда.
  • 📜 Элемент <plansql/> добавляет в события планы запросов.
  • ⚠️ EXCP — исключения, в том числе ошибки СУБД.

history="24" хранит логи 24 часа. Технологический журнал с DBMSSQL быстро растёт, поэтому каталог должен быть на диске с запасом места.

Не оставляйте полный журнал включённым надолго. На нагруженном сервере он сам становится нагрузкой на диск. Собрали данные за проблемный период — отключите.

Что смотреть в SQL Server

Кто кого блокирует прямо сейчас:

SELECT r.session_id, r.blocking_session_id, r.wait_type,
       r.wait_time, DB_NAME(r.database_id) AS db, t.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id <> 0;

Накопленные ожидания экземпляра показывает sys.dm_os_wait_stats. Как их читать:

Преобладающее ожиданиеО чём говорит
PAGEIOLATCH_*Данные не помещаются в память или медленные диски
WRITELOGМедленный диск журнала транзакций
LCK_M_*Ожидание блокировок СУБД
CXPACKET, CXCONSUMERПараллельные планы, проверьте MAXDOP
SOS_SCHEDULER_YIELDНехватка процессора или тяжёлые сканирования

Для длительной записи событий в самом SQL Server используйте Extended Events: сеанс с событиями долгих запросов и отчётом о взаимоблокировках (xml_deadlock_report). Старый SQL Profiler на рабочем сервере лучше не запускать — он сам грузит СУБД.

Порядок разбора медленной операции

  1. Воспроизвести операцию и найти её в технологическом журнале по событию DBMSSQL или CALL.
  2. Перевести имена таблиц (_AccumRg…, _Fld…) в объекты 1С через структуру хранения.
  3. Посмотреть план: сканирование большой таблицы, ошибка оценки строк, отсутствующий индекс.
  4. Если время уходит на ожидание, а не на выполнение — искать блокирующий сеанс.
  5. Править запрос или индекс в конфигурации, а не только железо.

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

Можно ли подключаться к базе 1С напрямую из SQL Server Management Studio?
Читать данные технически можно, но менять нельзя: платформа не узнает об изменениях, итоги и кэш разойдутся с таблицами. Изменения в базе делаются только средствами 1С.
Нужно ли создавать свои индексы в SQL Server для базы 1С?
Не стоит. При реструктуризации платформа пересоздаёт таблицы и удалит ваш индекс. Нужный индекс задают в конфигураторе свойством «Индексировать» или через измерения регистра.
Почему после переноса базы на новый сервер 1С стала медленнее?
Чаще всего не обновлена статистика и не настроены max server memory и MAXDOP. После восстановления из бэкапа обновите статистику и очистите кэш планов.
Что быстрее для 1С: SQL Server или PostgreSQL?
Зависит от нагрузки и настройки, однозначного победителя нет. Платформа поддерживает обе СУБД, а запросы и блокировки в типовых конфигурациях рассчитаны на работу с каждой из них.
Какая модель восстановления нужна для базы 1С?
Если допустима потеря данных за сутки — Simple с ежедневным бэкапом. Если нужно восстанавливать на любой момент — Full с регулярными копиями журнала транзакций.