Почему 1С 7.7 зависает при проведении документов после переноса на SQL Server и как это исправить?

Системный администратор 1С v7.7 IT и автоматизация бизнеса
← На главную

Перевод старой, но проверенной временем платформы 1С:Предприятие 7.7 с файлового режима (DBF) на клиент-серверный (MS SQL Server) — это классическая задача, с которой до сих пор сталкиваются системные администраторы и разработчики при поддержке исторических баз данных. На первый взгляд, процесс выглядит стандартно: создается пустая база на сервере, выполняется выгрузка данных в файл .dat и последующая загрузка в SQL-версию платформы. Все проходит без ошибок, но при первой же попытке провести, перепровести или отменить проведение любого документа система намертво зависает.

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

Анализ симптомов и диагностика с помощью SQL Server Profiler

Для того чтобы понять, что происходит в момент зависания, нам необходимо заглянуть «под капот» взаимодействия платформы 1С 7.7 и СУБД. Лучшим инструментом для этого является трассировка запросов через SQL Server Profiler. При попытке провести документ в 1С и последующем зависании интерфейса, Profiler фиксирует бесконечное выполнение одной и той же системной хранимой процедуры.

Типичный запрос, на котором останавливается выполнение, выглядит следующим образом:


exec _1sp_RA635_ClearRecalcDocActs '  I4U11  ','2018-10-29 00:00:00','2018-10-26 00:00:00',1,0,1

Проанализируем параметры этого вызова. Имя процедуры указывает на то, что выполняется очистка движений (таблицы итогов и движений регистров накопления, в данном примере — регистра RA635) перед проведением или при отмене проведения документа. В параметрах передаются идентификатор документа и две даты, ограничивающие период пересчета. Обратите внимание на даты: '2018-10-29 00:00:00' и '2018-10-26 00:00:00'. Они передаются в СУБД в виде текстовых строк стандартного формата YYYY-MM-DD HH:MM:SS.

Выясняем причину: конфликт локалей и форматов даты

Основная проблема кроется в особенностях интерпретации текстового представления дат типом данных datetime в СУБД MS SQL Server (начиная с версии SQL Server 2005 и выше).

Вопреки распространенному мнению, формат записи даты с дефисами YYYY-MM-DD не является абсолютно универсальным для устаревшего типа данных datetime в SQL Server. Его правильное распознавание напрямую зависит от языковых настроек сессии пользователя СУБД, под которым 1С 7.7 подключается к базе данных (параметр DATEFORMAT).

Рассмотрим детально, как это работает:

  1. Если у пользователя SQL по умолчанию установлен русский язык (Russian), то СУБД ожидает формат дат типа DMY (день-месяц-год).
  2. Получая от 1С строку '2018-10-29', SQL Server пытается разобрать ее в соответствии с правилом YYYY-DD-MM (поскольку дефисы заставляют СУБД использовать локальные настройки сессии).
  3. При попытке подставить число 29 на место месяца СУБД понимает, что 29-го месяца не существует, и генерирует внутреннюю ошибку преобразования типов: "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value" (Преобразование типа данных varchar в тип данных datetime привело к выходу значения за пределы допустимого диапазона).

Почему растет tempdb и зависает система?

В современных конфигурациях и платформах (например, в 1С 8.3) возникновение такой ошибки привело бы к мгновенному прерыванию транзакции и возврату понятного сообщения пользователю. Но архитектура платформы 1С 7.7 работает иначе:


Способ 1. Изменение языка по умолчанию для SQL-пользователя (Основное решение)

Самый простой, быстрый и безопасный способ устранить эту проблему — изменить языковые настройки для учетной записи (Login) в MS SQL Server, под которой авторизуется платформа 1С.

Выполним следующие шаги:

  1. Откройте утилиту Microsoft SQL Server Management Studio (SSMS) и подключитесь к вашему серверу баз данных с правами администратора (под учетной записью sa).
  2. В дереве объектов (Object Explorer) перейдите в ветку Security (Безопасность) -> Logins (Имена входа).
  3. Найдите учетную запись пользователя SQL, которую вы указывали в конфигураторе 1С 7.7 в меню "Параметры базы данных SQL" (например, это может быть пользователь sa, либо специально созданный пользователь, например, usr1c). Щелкните по нему правой кнопкой мыши и выберите Properties (Свойства).
  4. На открывшейся вкладке General (Общие) обратите внимание на самый нижний параметр страницы — Default Language (Язык по умолчанию).
  5. Смените установленный там язык (например, Russian) на English (или us_english).
  6. Нажмите кнопку OK для сохранения изменений.

После смены языка на English формат трактовки дат для этого пользователя автоматически изменится на MDY. Теперь SQL Server будет корректно распознавать строку формата YYYY-MM-DD как год-месяц-день, процедура выполнится за сотые доли секунды, транзакция успешно закроется, а база tempdb останется в стабильном состоянии.


Способ 2. Принудительная установка формата даты через системный триггер (Альтернатива)

Бывают ситуации, когда изменить глобальный язык по умолчанию для пользователя SQL невозможно (например, под этой же учетной записью работают сторонние интеграционные сервисы, завязанные на русскоязычный формат выгрузки дат или системных сообщений). В таком случае мы можем перехватывать момент подключения 1С 7.7 к СУБД и принудительно задавать формат обработки дат на уровне конкретной сессии.

Для этого мы создадим системный триггер на вход (Logon Trigger) в SQL Server. Разберем этот пример кода:


CREATE TRIGGER [1C_DateFormat_Fix]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
    IF ORIGINAL_LOGIN() = 'Имя_Вашего_Пользователя_1С'
    BEGIN
        EXEC('SET DATEFORMAT ymd;');
    END;
END;

Замените 'Имя_Вашего_Пользователя_1С' на реальный логин пользователя СУБД, под которым работает ваша база 1С 7.7. Этот триггер при каждом успешном подключении пользователя будет автоматически выполнять команду SET DATEFORMAT ymd;, что гарантирует правильное распознавание дат СУБД без изменения глобального языка интерфейса системы.


Способ 3. Проверка исходных данных на наличие поврежденных дат

В редких случаях проблема может усугубляться тем, что в исходной файловой базе (DBF) физически присутствуют «битые» или некорректные даты документов или их движений. Например, даты вида 00.00.0000, пустые значения или некорректные даты из далекого прошлого/будущего (например, 01.01.0100 или 31.12.9999).

Диапазон допустимых дат для типа данных datetime в MS SQL Server строго ограничен: от 1 января 1753 года до 31 декабря 9999 года. Любая дата, выходящая за эти рамки (например, «нулевая» дата), вызывает ошибку преобразования типов на стороне сервера.

Для исправления таких ошибок рекомендуется провести аудит данных перед выгрузкой:

  1. В исходной файловой базе выполните процедуру "Тестирование и исправление ИБ" (меню Администрирование в Конфигураторе), обязательно отметив пункты проверки физической целостности и реиндексации таблиц.
  2. Если тестирование не помогло, воспользуйтесь сторонними DBF-редакторами для проверки ключевых таблиц базы данных. Особое внимание обратите на таблицу журнала документов 1CJOURN и таблицы движений регистров (начинаются с префикса RA), отсортировав колонки с датами по возрастанию и убыванию, чтобы выявить некорректные или пустые значения и вручную исправить их на валидные даты.

Применение одного из описанных выше способов (в первую очередь — изменения языка по умолчанию на English для SQL-пользователя) гарантированно решает проблему «зависания» платформы 1С 7.7 и обеспечивает стабильную и быструю работу переведенной базы данных в клиент-серверном режиме.

← На главную