Перенос устаревших систем 1С Предприятие 7.7 на современные серверные платформы, такие как Windows Server 2012/2016 и MS SQL Server 2012/2014/2017, часто сопровождается критическими ошибками. Одной из самых неприятных является сообщение: «База данных уже открыта и одновременно к ней может обращаться только один пользователь». Эта ошибка обычно возникает в самом конце процесса загрузки данных, при переиндексации или при попытке монопольного входа.
В этой статье мы подробно разберем причины возникновения данной ситуации и рассмотрим комплекс мер — от настройки параметров SQL-сервера до программных «хитростей» внутри самой 1С.
Проблема кроется в том, как 1С 7.7 пытается управлять монопольным доступом. Для этого платформа переводит базу данных в режим SINGLE_USER. В современных версиях SQL Server (начиная с 2012) изменились механизмы работы фоновых системных процессов. Когда 1С пытается захватить базу монопольно, она проверяет количество активных соединений через системное представление master..sysprocesses. Если в этот момент к базе подключен системный процесс (например, сбор статистики или очистка), SQL Server не может завершить переход в SINGLE_USER, и 1С выдает ошибку.
Первым делом проанализируем права пользователя, под которым 1С подключается к серверу. Даже если пользователь наделен правами db_owner, в новых версиях SQL ему может не хватать прав на просмотр состояния сервера для корректного определения подключений.
Разберем, как выдать необходимые разрешения. Выполните в SQL Server Management Studio (SSMS) следующий скрипт, заменив имя пользователя на ваше:
USE master
GO
GRANT VIEW SERVER STATE TO [Имя_Вашего_Пользователя]
GRANT VIEW ANY DEFINITION TO [Имя_Вашего_Пользователя]
GO
Это позволит 1С корректно видеть список процессов и понимать, что база действительно свободна от других пользовательских сессий.
Существуют специфические настройки SQL-сервера, которые мешают 1С захватить базу в монопольном режиме. Проанализируем настройки самой базы данных в SSMS (свойства базы, раздел Options):
False. Когда этот параметр включен, SQL Server может в любой момент инициировать процесс создания статистики, что блокирует монопольный доступ.False.False. Этот параметр — «враг» для 1С 7.7, так как постоянное закрытие/открытие базы вызывает конфликты блокировок.20. Это помогает избежать длительных зависаний при завершении транзакций загрузки.Важно помнить, что отключение автообновления статистики потребует от администратора настройки регламентного задания для ручного обновления статистики (Maintenance Plan), иначе производительность базы со временем упадет.
Одной из скрытых причин удержания базы является процесс Ghost Cleanup (очистка «фантомных» записей, помеченных на удаление). Рассмотрим, как временно его отключить, чтобы завершить загрузку данных без ошибок.
Для этого используются флаги трассировки. В консоли запросов SQL выполните:
-- Включение флага для отключения Ghost Cleanup
DBCC TRACEON (661, -1);
GO
После этого попробуйте повторить загрузку данных. Когда процесс будет завершен и база будет успешно развернута, флаг необходимо выключить:
-- Выключение флага
DBCC TRACEOFF (661, -1);
GO
Если ошибка возникает при перепроведении документов или пересчете итогов, мы можем применить программный метод принудительного перевода базы в многопользовательский режим прямо из 1С. Это особенно полезно, когда 1С уже захватила базу, но «зависла» на проверке монопольности.
Посмотрим на пример кода, который можно добавить в обработку или в процедуру ПриНачалеРаботыСистемы (при условии использования внешней компоненты для прямого доступа к SQL, например, ODBCRecordSet):
ЗапросСКЛ = СоздатьОбъект("ODBCRecordSet");
ТекстЗапроса = "
|ALTER DATABASE CURRENT
|SET MULTI_USER";
Если ЗапросСКЛ.Выполнить(ТекстЗапроса) <> 1 Тогда
Сообщить("Ошибка принудительного сброса монопольного режима: " + ЗапросСКЛ.ПолучитьОписаниеОшибки());
КонецЕсли;
Этот метод позволяет 1С продолжить работу, «обманывая» проверку режима SINGLE_USER. Однако будьте осторожны: выполнение операций пересчета итогов в MULTI_USER может привести к непредсказуемым результатам, если в базе в это время работают другие люди.
В версиях SQL Server 2012 и выше реализована оптимизация Deferred Segment Creation (отложенное создание сегментов). Если в 1С есть объекты метаданных без данных (например, пустая Книга Покупок), SQL может физически не создать таблицу. Конфигуратор 1С 7.7 при попытке индексации таких «фантомных» таблиц может выдавать ошибку доступа.
Разберем способ решения: перед загрузкой создайте небольшую обработку, которая создает хотя бы по одному пустому элементу (или пустой строке документа) в каждом типе метаданных. Это заставит SQL Server гарантированно создать физические таблицы.
Для работы на новых ОС и SQL крайне рекомендуется использовать патченную версию BkEnd.dll (так называемый Solution7). Проверьте следующие моменты при установке:
BkEnd.dll и BkEndUtls.dll должны находиться в папке BIN платформы 1С.lpc:ServerName (для использования Shared Memory, если SQL и 1С на одном сервере), это минимизирует сетевые задержки и ошибки протокола Named Pipes.При использовании «секретного релиза» важно, чтобы в BIN не оставалось старых оригинальных файлов. Рекомендуется переименовать оригинальный BkEnd.dll в BkEnd_orig.dll перед заменой.
Подводя итог, можно сказать, что решение проблемы всегда комплексное. Чаще всего помогает связка из Решения 1 (права пользователя) и Решения 2 (отключение автостатистики). Проанализируйте логи SQL-сервера в момент возникновения ошибки: если вы видите записи о переключении SINGLE_USER to ON и сразу MULTI_USER to ON, значит, какой-то фоновый процесс SQL успевает «проскочить» между этими командами 1С, и вам стоит обратить внимание на Решение 3.