В процессе активной разработки в среде 1С:Предприятие программисты регулярно сталкиваются с необходимостью изменения структуры метаданных: удалением реквизитов, справочников, документов или их табличных частей. Обычно эти действия проходят бесшовно, однако бывают ситуации, когда после удаления табличной части в Конфигураторе и успешного обновления конфигурации базы данных, физическая таблица в СУБД MS SQL Server со всеми записями остается нетронутой. При этом программный метод ПолучитьСтруктуруХраненияБазыДанных() её больше не видит.
В этой статье мы подробно разберем, почему возникает этот феномен, чем он опасен для стабильности системы, какова его связь с критической ошибкой SDBL и как правильно и безопасно устранить "осиротевшие" таблицы из вашей базы данных.
При штатном удалении табличной части объекта платформа 1С должна транслировать это действие в СУБД в виде SQL-команды DROP TABLE для соответствующей физической таблицы (например, _Document40_VT41). Если этого не произошло, мы имеем дело с нарушением транзакционной целостности на стыке платформы и СУБД. Выделим основные причины такого поведения:
ldf или кратковременный сетевой сбой), транзакция удаления старой таблицы могла откатиться на уровне SQL Server. Однако на уровне метаданных 1С (в системных таблицах DBSchema и Params) изменения уже зафиксировались. Как результат — 1С «забывает» о существовании таблицы, а SQL продолжает её хранить._NG и _NGS.DROP TABLE, отложив или полностью проигнорировав физическое удаление объекта.Многие разработчики считают, что лишняя таблица в SQL — это лишь небольшая потеря дискового пространства. Однако это заблуждение. Самая большая опасность кроется в возникновении критической ошибки:
Ошибка SDBL: Ошибка обновления конфигурации базы данных. Для одного ссылочного кода существует более одной таблицы в базе данных.
Давайте проанализируем механизм генерации имен в 1С. Платформа выделяет внутренние целочисленные идентификаторы (ссылочные коды) для создаваемых объектов СУБД. Например, для документа выделяется код 40, а для его табличной части — код 41. Если вы восстанавливаете базу данных из резервной копии SQL без перезапуска службы сервера 1С, менеджер кластера (процесс rmngr.exe) продолжает хранить старый кэш распределения этих кодов.
При создании нового объекта метаданных платформа может выдать ему тот же свободный, по её мнению, числовой код. В процессе обновления конфигурации 1С пытается создать в SQL-базе таблицу с этим кодом, обращается к СУБД и обнаруживает, что физическая таблица с таким именем (оставшаяся от удаленного ранее объекта) уже существует и содержит данные. Происходит жесткий конфликт SDBL, блокирующий любые дальнейшие обновления конфигурации.
Рассмотрим несколько надежных способов устранения "осиротевших" таблиц и исправления сопутствующих ошибок конфигурации.
Поскольку платформа 1С через функцию ПолучитьСтруктуруХраненияБазыДанных() данную таблицу больше не идентифицирует, для системы эта таблица является абсолютным мусором. Её можно безопасно удалить вручную.
Важно: Перед выполнением любых прямых запросов к СУБД обязательно сделайте резервную копию базы данных средствами SQL Server!
Разберем по шагам процесс удаления таблицы через MS SQL Server Management Studio (SSMS):
sa).
SELECT COUNT(*) FROM dbo._Document40_VT41;
IF OBJECT_ID('dbo._Document40_VT41', 'U') IS NOT NULL
DROP TABLE dbo._Document40_VT41;
После успешного выполнения команды физический мусор будет устранен, и потенциальный конфликт имен при создании новых объектов конфигурации полностью нивелируется.
Это самый надежный, штатный и безопасный способ избавления от любого физического мусора в СУБД, рекомендуемый самой фирмой 1С.
Проанализируем этот процесс:
.dt платформа 1С обращается исключительно к актуальным метаданным конфигурации. Она последовательно считывает данные только из тех таблиц, которые зарегистрированы в системных таблицах DBSchema..dt не попадают..dt в новую пустую базу данных СУБД платформа заново создает структуру таблиц "с нуля". В новой базе будут присутствовать только актуальные таблицы, а весь накопленный мусор исчезнет.Если вы часто проводите манипуляции с восстановлением баз из SQL-бэкапов (особенно в тестовых контурах разработки), возьмите за железное правило:
После восстановления базы данных средствами СУБД всегда перезапускайте службу сервера 1С:Предприятия!
Если нет возможности перезапустить всю службу целиком (например, на рабочем сервере запущено множество других баз), выполните перезапуск процесса rmngr.exe или удалите базу из списка консоли администрирования 1С и добавьте её заново. Это принудительно очистит внутренний кэш менеджера кластера и предотвратит наложение новых транзакций на старые физические таблицы СУБД.
Если при попытке обновиться вы уже получили блокирующую ошибку дублирования кодов таблиц, выполните следующий простой обходной алгоритм без прямого вмешательства в СУБД:
ВременныйРеквизит с типом Булево).F7). Данное действие заставит платформу принудительно запустить полную реструктуризацию этого объекта, в ходе которой она перезапишет схему метаданных в СУБД и корректно перераспределит внутренние идентификаторы.Использование этого несложного приема позволяет быстро вернуть базу данных в рабочее состояние без ручной корректировки системных таблиц СУБД.