Как перевести 1С 7.7 на MS SQL Server 2008 и 2012 без режима совместимости?

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

При эксплуатации крупных информационных баз 1С:Предприятие 7.7 на современных версиях СУБД системные администраторы и разработчики часто сталкиваются с жесткими техническими ограничениями. В MS SQL Server 2012 уровень обратной совместимости со старыми базами (уровень 80, соответствующий SQL Server 2000) был полностью упразднен. Возникает закономерный вопрос: насколько стабильно работает связка 1С 7.7 с MS SQL Server 2008 и MS SQL Server 2012 в режиме совместимости по умолчанию (уровни 100 и 110), какие «подводные камни» возникают при промышленной эксплуатации и как устранить критические просадки производительности?

Разберем практический опыт и детальные технические шаги, позволяющие эксплуатировать базы данных размером от 50 до 500 ГБ с числом активных пользователей более 100 человек без отката уровня совместимости.

Причины возникновения проблем при отказе от режима совместимости

Проанализируем ключевые причины, из-за которых штатный исполняемый файл платформы 7.7 дает сбой или приводит к колоссальным зависаниям на новых СУБД:

  1. Удаление системной процедуры sp_dboption: начиная с SQL Server 2012, процедура sp_dboption отсутствует в СУБД. Платформа 1С 7.7 вызывает её при попытке входа в монопольном режиме и при сохранении метаданных в конфигураторе. При её отсутствии монопольный вход и реструктуризация блокируются.
  2. Ошибочный план выполнения в методе ПодчиненныеДокументы(): штатный механизм 1С при выборке подчиненных документов без явного указания дат генерирует запрос с фиктивной максимальной датой (31.12.9999). В оптимизаторе запросов SQL Server 2008/2012 это приводит к выбору плана Index Scan (полное сканирование индекса) по таблицам _1SCRDOC и _1SJOURN вместо точечного поиска Index Seek, вызывая блокировки и тайм-ауты.
  3. Ограничения прав на представление sysprocesses: штатный движок платформы опрашивает master..sysprocesses для проверки числа активных сеансов. В новых версиях SQL Server пользователь без полных прав администратора видит только свои процессы, что приводит к ложным ошибкам о невозможности блокировки базы.
  4. Проверка драйвера ODBC: оригинальный релиз требует устаревшие версии ODBC-драйвера (sqlsrv32.dll), выдавая ошибку при подключении через современные ОС.

Решение 1. Устранение зависаний и тайм-аутов при выборке подчиненных документов

Выясним причину критических тормозов: когда в коде 1С 7.7 вызывается стандартный метод выборки подчиненных документов без передачи временного диапазона, запрос зависает из-за смены логики кардинальности оптимизатора SQL.

Рассмотрим два способа исправления этой проблемы:

Способ А. Быстрое исправление в штатном коде (указание интервала дат)

Если требуется устранить проблему максимально быстро без масштабного переписывания логики, достаточно передать в метод границы дат. Оптимизатор SQL Server при наличии хотя бы одной границы использует совершенно другой план выполнения, который выполняется мгновенно:


// Было: медленный запрос со сканированием таблицы
Док = СоздатьОбъект("Документ");
Док.ВыбратьПодчиненныеДокументы(,, ТекущийДокумент);

// Стало: ограничение интервалом дат
ДатаНач = ТекущийДокумент.ДатаДок - 100; // отступаем 100 дней назад
ДатаКон = ТекущийДокумент.ДатаДок + 100; // либо РабочаяДата()
Док.ВыбратьПодчиненныеДокументы(ДатаНач, ДатаКон, ТекущийДокумент);

Если для бизнес-логики необходима вся история за длительный период, можно указать интервал даже в десятки лет назад — передача конкретной даты исключает подстановку фиктивного значения 31.12.9999 и заставляет оптимизатор применять точечный Index Seek.

Способ Б. Переход на прямые запросы через 1С++

Для высоконагруженных систем с базой объемом свыше 50–100 ГБ наиболее эффективным решением является использование внешней компоненты 1С++ и прямых SQL-запросов. Это полностью снимает нагрузку с движка платформы и позволяет выбирать только нужные поля, фильтровать подчиненные документы по видам и статусу проведения прямо на уровне СУБД:


ЗапросSQL = СоздатьОбъект("ODBCRecordset");
ТекстЗапроса = "
|SELECT 
|   Doc.IDDOC as [Док $Документ]
|FROM 
|   _1SCRDOC as Links WITH (NOLOCK)
|INNER JOIN 
|   _1SJOURN as Doc WITH (NOLOCK) ON Links.CHILD_DATE_TIME_IDDOC = Doc.DATE_TIME_IDDOC
|WHERE 
|   Links.PARENTVAL = :ВыбРодитель
|";
ЗапросSQL.УстановитьТекстовыйПараметр("ВыбРодитель", ТекущийДокумент);
ТЗ = ЗапросSQL.ВыполнитьИнструкцию(ТекстЗапроса);

Решение 2. Адаптация СУБД для работы с монопольным режимом (SQL 2012+)

Разберем по шагам, как решить проблему отсутствия процедуры sp_dboption на стороне MS SQL Server 2012 и выше. Для этого создадим замещающую процедуру в базе данных master, которая будет транслировать устаревшие команды платформы в актуальные инструкции T-SQL:


USE [master]
GO
CREATE PROCEDURE [dbo].[sp_dboption]
    @dbname sysname = NULL,
    @optname varchar(35) = NULL,
    @optvalue varchar(10) = NULL
AS
BEGIN
    SET NOCOUNT ON;
    IF @optname = 'single user'
    BEGIN
        IF @optvalue = 'TRUE'
            EXEC('ALTER DATABASE [' + @dbname + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE');
        ELSE
            EXEC('ALTER DATABASE [' + @dbname + '] SET MULTI_USER');
    END
END
GO

Данная процедура перехватывает команды 1С 7.7 при открытии базы в монопольном режиме и корректно переключает базу данных.

Решение 3. Настройка прав доступа и системных представлений

Посмотрим на проблему контроля сессий пользователей. 1С 7.7 использует обращение к sysprocesses для определения числа работающих пользователей и блокировок.

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


USE [master]
GO
GRANT VIEW SERVER STATE TO [ИмяПользователя1С];
GO

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

Решение 4. Тонкая настройка сервера (MAXDOP и tempdb)

Платформа 1С 7.7 исторически проектировалась под однопоточные запросы. При использовании современных многоядерных процессоров оптимизатор SQL Server может строить параллельные планы с распараллеливанием одного запроса на несколько ядер. Это приводит к ожиданиям типа CXPACKET и взаимным блокировкам пользовательских транзакций.

  1. Настройка параллелизма: в свойствах экземпляра SQL Server (параметр Max Degree of Parallelism / MAXDOP) обязательно установите значение 1. Это исключит параллелизм на уровне отдельных транзакций 1С.
  2. Оптимизация базы tempdb: разбейте базу данных tempdb на несколько файлов данных одинакового размера (по числу физических ядер процессора, обычно от 4 до 8 файлов). Для SQL Server 2008/2012 рекомендуется включить флаг трассировки 1118 для предотвращения конфликтов распределения экстентов.
  3. Отключение проверки сортировки: чтобы исключить ошибку несоответствия порядка сортировки кодовой страницы, поместите в каталог базы или в каталог BIN платформы пустой файл OrdNoChk.prm.

Практика промышленной эксплуатации показывает, что при выполнении указанных настроек базы данных объемом 150–500 ГБ на 70–180 одновременных пользователей стабильно и быстро функционируют на MS SQL Server 2008 и 2012 без включения режима пониженной совместимости.

← На главную