Каждый администратор систем «1С:Предприятие» рано или поздно сталкивается с ситуацией, когда стабильно работающая система внезапно начинает зависать. Пользователи жалуются на «песочные часы», проведение документов останавливается, а при попытке зайти в консоль администрирования кластера мы видим пугающую картину: у одного или нескольких сеансов стремительно и непрерывно растет показатель «Захвачено СУБД» в секундах. При этом попытка принудительно завершить сеанс зависшего пользователя приводит к мертвой блокировке самой консоли кластера, а единственным спасением кажется полная перезагрузка службы Агента сервера 1С. Но уже через 20 минут ситуация повторяется.
В этой статье мы подробно и по шагам разберем, почему возникает эта проблема, как провести глубокую диагностику на стороне сервера приложений и СУБД MS SQL Server, и какие конкретные действия помогут навсегда устранить эти зависания.
Многие технические специалисты ошибочно полагают, что рост показателя «Захвачено СУБД» (в технологическом журнале и API он называется db-proc-took) свидетельствует исключительно о транзакционных блокировках. На самом деле этот счетчик работает шире: он фиксирует время непрерывного удержания физического соединения с СУБД рабочим процессом 1С для конкретного сеанса.
Бесконечный рост этого показателя может быть вызван тремя основными причинами:
МенеджерВременныхТаблиц, и ссылка на него помещается в долгоживущую переменную (переменную модуля формы, модуля объекта или в параметры сеанса), то физическое соединение с SQL-сервером не разовьется до тех пор, пока этот объект не будет уничтожен. Пул соединений сервера 1С истощается, и база начинает «вешаться».Автор темы столкнулся с характерным симптомом: «При попытке удалить пользователя зависает консоль кластера». Это происходит из-за повреждения или взаимной блокировки файлов сеансовых данных, которые сервер 1С хранит на диске. Обычная очистка пользовательского кэша здесь бесполезна. Нам необходимо принудительно очистить сеансовый кэш службы.
Выполним процедуру очистки по шагам:
services.msc) или консоль Linux и остановим службу «Агент сервера 1С:Предприятия».C:\Program Files\1cv8\srvinfo\ (или C:\Program Files (x86)\1cv8\srvinfo\ для 32-разрядной службы).reg_1541.snccntx (например, snccntx5e9a4d...). Именно здесь хранятся кэшированные данные активных сеансов в формате файлов *.dat. При аварийных завершениях процессов эти файлы могут повреждаться, вызывая зависание консоли при попытке считать информацию о сеансах.snccntx. Не беспокойтесь, сервер 1С автоматически пересоздаст ее при следующем запуске.Когда система зависла, а перезапускать сервер приложений 1С нельзя (поскольку в других базах работают пользователи), мы можем решить проблему точечно со стороны СУБД. Нам необходимо найти транзакцию, которая выступает «главным блокировщиком» (Head Blocker), и принудительно завершить ее.
Для этого откроем SQL Server Management Studio (SSMS) и выполним следующий диагностический запрос к системным представлениям:
SELECT
er.blocking_session_id AS [ID блокировщика],
er.session_id AS [Заблокированный ID],
es.program_name AS [Приложение 1С],
es.login_name AS [Пользователь SQL],
er.wait_time AS [Время ожидания (мс)],
er.wait_type AS [Тип ожидания],
est.text AS [Текст SQL-запроса]
FROM sys.dm_exec_requests er
JOIN sys.dm_exec_sessions es ON er.session_id = es.session_id
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) est
WHERE er.blocking_session_id <> 0;
Проанализируем результат выполнения этого запроса. В колонке [ID блокировщика] мы увидим идентификатор системного процесса (SPID), который держит блокировку и не дает работать остальным. Выяснив этот ID (например, 74), мы можем мгновенно убить его на уровне СУБД с помощью команды:
KILL 74;
Это приведет к немедленному откату зависшей транзакции в MS SQL. При этом рабочий процесс сервера 1С перенаправит пострадавшего пользователя на новое соединение, выдав ему ошибку о разрыве связи, но вся остальная база продолжит работу в штатном режиме без перезапуска службы Агента.
Очень часто мертвые сеансы с растущим показателем «Захвачено СУБД» возникают из-за нестабильной работы сети (особенно если пользователи работают через Wi-Fi, VPN или тонкие клиенты). При кратковременной потере пакетов клиентское приложение 1С закрывается, но сервер 1С не получает сетевой пакет об отключении (FIN). Сервер продолжает считать сеанс активным, удерживая все блокировки в SQL.
Чтобы операционная система сервера своевременно определяла «обрыв» таких зависших соединений, настроим параметры TCP Keep-Alive в реестре Windows на серверах приложений и СУБД:
regedit).HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\ParametersDWORD (32-бит):
KeepAliveTime — установим значение 300000 (в десятичной системе). Это заставит ОС проверять активность простаивающего соединения каждые 5 минут (вместо стандартных 2 часов).KeepAliveInterval — установим значение 1000 (в десятичной системе). Это интервал между повторными проверками, если ответ на первый запрос активности не был получен.В обсуждении на форуме упоминается, что у автора используется 32-разрядный сервер приложений 1С. Это критическое «узкое горлышко» для современных баз данных. Архитектура 32-битных систем накладывает жесткое ограничение: один рабочий процесс rphost не может адресовать более 4 ГБ оперативной памяти (на практике зависания и падения из-за фрагментации памяти начинаются уже при достижении процессом 3-3.2 ГБ).
Когда пользователь запускает тяжелый отчет или групповую обработку, рабочий процесс rphost пытается обработать эти данные. Память процесса мгновенно упирается в лимит, он впадает в состояние бесконечного свопинга или утечки памяти, зависает сам и «вешает» соединение с СУБД, вызывая бесконечный рост «Захвачено СУБД».
Рекомендации по устранению лимитов памяти:
Допустимый объем памяти — например, 3000000 КБ (около 3 ГБ).Интервал превышения допустимого объема памяти — 300 секунд. Это позволит серверу безопасно и автоматически заменять «раздувшиеся» процессы новыми без прерывания работы пользователей.Иногда зависание происходит на стороне СУБД в момент, когда база данных или служебная база tempdb исчерпывают свободное место и пытаются расширить свои файлы на диске. Рассмотрим этот процесс подробнее.
Если в настройках авторасширения (Autogrowth) базы данных установлен слишком маленький шаг (например, по умолчанию 1 МБ) или, наоборот, слишком большой в процентах (например, 10%), СУБД во время записи данных останавливает все транзакции (что вызывает зависание сеансов 1С и рост времени захвата СУБД) для проведения физического выделения места на диске. Если диск медленный, эта процедура может занимать десятки секунд, парализуя работу пользователей.
Настроим базу данных правильно:
.mdf) установим фиксированный шаг авторасширения (Autogrowth) в мегабайтах (например, 512 MB или 1024 MB вместо процентов)..ldf) установим авторасширение в размере 256 MB или 512 MB.tempdb несколько файлов данных одинакового размера (по количеству ядер процессора, но не более 8) с фиксированным авторасширением в 256 MB.В теме указана версия платформы 8.3.6.2449. Это старый релиз, содержащий известный баг: при определенных условиях во время аварийного прерывания транзакции рабочий процесс rphost мог «забыть» отправить команду ROLLBACK TRANSACTION в SQL Server. В итоге транзакция «зависала» в СУБД в открытом состоянии навсегда.
Дополнительно ситуацию ухудшают так называемые «демонические» обновления конфигурации (динамическое обновление без выгона пользователей), которые часто приводят к рассинхронизации структуры метаданных и физических таблиц SQL.
Для исправления структуры таблиц и очистки от накопленных ошибок выполним реструктуризацию базы данных:
ВременнаяОбработкаРеструктуризации).F7). В этот момент платформа проверит соответствие метаданных физическим таблицам СУБД.F7). Данный прием инициирует принудительную реструктуризацию и обновление индексов основных таблиц, исправляя возможные логические несоответствия СУБД.Администрирование -> Тестирование и исправление, выбрав пункты «Реиндексация таблиц» и «Пересчет итогов».Проанализировав все описанные шаги и внедрив эти настройки, мы обеспечим отказоустойчивость серверов 1С и СУБД, исключим появление «зомби-сеансов», стабилизируем работу пользователей и избавимся от необходимости постоянного ручного перезапуска службы Агента.