При работе с базами данных 1С:Предприятие 8.3 администраторы и разработчики часто сталкиваются с ситуацией, когда после восстановления информационной базы средствами СУБД (например, из .bak файла Microsoft SQL Server) попытка программного или интерактивного создания нового документа или справочника заканчивается ошибкой "Номер не уникален". При этом в исходной базе, с которой снималась копия, такой проблемы не наблюдалось.
В рамках данной статьи мы подробно разберем, почему возникает этот эффект, как работает внутренний механизм генерации номеров в платформе и какие существуют способы решения этой проблемы — от быстрых программных команд до радикальных методов очистки кэша сервера.
Для того чтобы понять природу ошибки, проанализируем архитектуру современных версий платформы 1С. Начиная с версии 8.2, за выдачу новых номеров отвечает специальный механизм — Сервис нумерации объектов (Sequence Number Manager или SNM). Этот сервис является частью кластера серверов 1С и работает в оперативной памяти процесса rphost.
Рассмотрим ключевые особенности работы этого сервиса:
snm). Когда вы восстанавливаете базу через SQL Management Studio, данные в таблицах СУБД меняются (откатываются назад или обновляются), но кластер 1С об этом "не знает".Самым правильным и штатным способом решения проблемы является использование встроенного метода платформы ОбновитьНумерациюОбъектов(). Этот метод принудительно заставляет сервис нумерации пересчитать последние номера, обратившись напрямую к данным в таблицах СУБД.
Рассмотрим, как применить этот метод на практике. Проанализируем два варианта вызова:
Вариант А: Обновление для всех объектов сразу
Если база небольшая или вы не знаете точно, в каких именно справочниках и документах возник сбой, можно вызвать метод без параметров. В этом случае система просканирует все метаданные.
// Выполняется в контексте сервера
ОбновитьНумерациюОбъектов();
Вариант Б: Точечное обновление (рекомендуется для больших баз)
На высоконагруженных системах полное сканирование может вызвать временные задержки. Правильнее передать в метод массив метаданных или конкретный тип объекта. Разберем пример кода для внешней обработки:
// Обновление нумерации для конкретных типов документов
МассивМетаданных = Новый Массив;
МассивМетаданных.Добавить(Метаданные.Документы.РеализацияТоваровУслуг);
МассивМетаданных.Добавить(Метаданные.Справочники.Номенклатура);
ОбновитьНумерациюОбъектов(МассивМетаданных);
Для запуска этого кода рекомендуется создать простую внешнюю обработку с одной кнопкой, так как метод ОбновитьНумерациюОбъектов доступен только на стороне сервера.
Многие специалисты отмечают, что проблема решается сама собой, если сделать выгрузку информационной базы в файл .dt и загрузить ее обратно. Посмотрим, почему это происходит: при загрузке данных из .dt платформа фактически пересоздает базу данных "с нуля" и принудительно инициализирует все счетчики нумерации, считывая актуальные максимумы из данных.
Однако у этого метода есть существенные минусы:
Если программные методы по какой-то причине недоступны (например, невозможно зайти в базу под пользователем из-за критических ошибок), существует системный способ сброса счетчиков. Выясним, как это сделать вручную:
C:\Program Files\1cv8\srvinfo\reg_1541\.snm. Именно здесь физически хранятся закэшированные номера.snm или переименуйте ее.После выполнения этих действий при первом обращении к любому объекту (создании нового документа) сервер будет вынужден прочитать максимальный номер из SQL-таблицы, так как локальный кэш будет пуст.
Проанализируем ситуации, когда даже ОбновитьНумерациюОбъектов() может не помочь с первого раза:
1. Испорченные номера (префиксы). Если в базе вручную был создан документ с номером типа "99999", то автоматический нумератор "упрется" в этот предел. Обновление нумерации просто подтвердит, что 99999 — это максимум, и новые номера выдаваться не будут. В таком случае сначала нужно найти и исправить "кривой" номер вручную.
2. Резервирование номеров порциями. Платформа 1С умеет захватывать сразу несколько номеров вперед для ускорения (свойство "Автонумерация" в метаданных). При восстановлении SQL-копии эти "зарезервированные" номера могут быть потеряны или войти в конфликт. Использование ОбновитьНумерациюОбъектов() сбрасывает эти порции.
3. Распределенные базы (РИБ). Если вы восстанавливаете из SQL-бекапа один из узлов распределенной информационной базы, обязательно выполните обновление нумерации сразу после восстановления. Иначе вы рискуете получить дубли номеров, которые "прилетят" из других узлов при синхронизации, что создаст огромные проблемы при обмене данными.
Подведем итог нашему исследованию. Если после манипуляций с SQL-базой вы получили ошибку уникальности номеров, придерживайтесь следующего алгоритма:
rphost (или всю службу сервера 1С), это очистит оперативную память.ОбновитьНумерациюОбъектов() через консоль кода или внешнюю обработку.snm в каталоге сервера.Помните, что восстановление базы через SQL — это "нештатная" операция с точки зрения логики кластера 1С, поэтому процедура обновления нумерации должна стать обязательным пунктом в вашем регламенте восстановления систем из резервных копий.