89 минут против 6: реструктуризация большой серверной базы, которая падает без ошибки
В статье «Claude Code + EDT на БП КОРП: три месяца, 328 коммитов и 40 правил» этой истории достался один абзац: обновление большой серверной базы через EDT безрезультатно шло 89 минут, а пакетный конфигуратор с ключом -Server закончил его за 6. Здесь разбор целиком, с командами и порядком действий.
Стенд тот же: 1С:Бухгалтерия предприятия КОРП 3.0 на платформе 8.5, серверная база на MSSQL, разработка в EDT. На одной машине живут три кластера разных версий платформы. Обе аварии, о которых пойдет речь, начались с нештатной остановки сервера: первая с аппаратного сбоя, вторая с аварийного завершения. Вывод получился общий: когда реструктуризация большой серверной базы падает молча, искать причину в своем коде почти бесполезно. Сначала нужны факты, потом другой путь применения конфигурации.
Как это выглядит
Симптомов четыре, и они легко сбивают с толку, потому что модель в EDT при этом чистая: ревалидация проходит, get_project_errors не показывает ничего нового.
Первый и самый неприятный: конфигуратор или агент EDT вылетает на 0 % «Обработки структуры базы данных» без внятного сообщения. В EDT это выглядит как «Потеряно соединение с агентом конфигуратора» или Designer agent has closed communication channel.
Второй: обновление падает с ошибкой загрузки конфигурации, и объект в ней «переползает» от попытки к попытке:
Ошибка загрузки/выгрузки конфигурации
Неизвестный объект метаданных - Report.<Имя>.Template.<Макет>
Третий: нельзя добавлять объекты метаданных без загрузки родительского объекта. В стеке у второго и третьего один и тот же метод, importIncrementalXmlToInfobase, то есть инкрементальная выгрузка.
Четвертый появляется после попыток лечения: Ошибка блокировки информационной базы для конфигурирования. С этой информационной базой уже работает конфигуратор, хотя конфигуратор вы не открывали.
Почему инкремент хрупкий
EDT хранит у себя снимок того, что уже выгружено в базу, и при обновлении отправляет только разницу. Пока снимок и база совпадают, это быстро и удобно. Аварийная перезагрузка сервера, падение агента посреди загрузки или восстановление базы из бэкапа ломают это соответствие, и EDT начинает слать пакет, который ссылается на объекты, которых в базе нет. Отсюда «Неизвестный объект метаданных» при совершенно целом проекте.
Лечится это полной перезаписью конфигурации вместо инкремента. Для структурных изменений (новые документы, регистры) мы теперь делаем полную выгрузку раз в порцию работ, а инкремент оставляем для правок кода.
Отдельно о бэкапах, потому что после аварии рука тянется восстановить все. Проект EDT из бэкапа не поднимаем никогда: в исходниках последние наработки, их и потеряете. Восстанавливать можно только информационную базу, либо перезаписывать конфигурацию из EDT поверх нее.
Есть и случай, когда инкремент ни при чем. Если объект создан не конструктором EDT, а сгенерирован скриптом и положен файлом .mdo, F5 перечитает файлы, но в состав конфигурации (Configuration.mdo) объект не добавит. Папка есть, записи в составе нет, и платформа отвечает тем самым «без загрузки родительского объекта». Лечение: добавить строку вида <documents>Document.Имя</documents> в нужную секцию состава, потом F5, ревалидация и обновление.
Не гадать: журнал Windows и техжурнал
Когда конфигуратор вылетает без сообщения, хочется перебирать версии: мало памяти, кончился диск, побились данные, виноват последний регистр. Мы прошли этот путь и потеряли на нем время. Работает другой порядок: сначала снять факты, потом думать.
Журнал Windows. Application, события Application Error и Windows Error Reporting. Там видно имя сбойного приложения (1cv8.exe), сбойный модуль и код исключения. У нас это был backend.dll с кодом 0xc0000005, то есть Access Violation. Уже это сужает поиск: падает платформа, а не ваш код.
Технологический журнал 1С. Файл logcfg.xml кладется в C:\Program Files\1cv8\<версия>\bin\conf\, и здесь первая ловушка: версия должна быть та, которой вы реально запускаете конфигуратор. У клиента и кластера версии могут отличаться, и журнал, положенный не в тот каталог, молча ничего не пишет.
Начинать стоит с узкого варианта: дамп при падении плюс исключения.
<config xmlns="http://v8.1c.ru/v8/tech-log">
<dump create="1" location="C:\1C_dumps" type="0"/>
<log location="C:\1C_TJ" history="24">
<event><eq property="name" value="EXCP"/></event>
<event><eq property="name" value="EXCPCNTX"/></event>
<property name="all"/>
</log>
</config>
Если по исключениям не видно, какая операция шла перед падением, включайте все события:
<log location="C:\1C_TJ_ALL" history="2">
<event><ne property="name" value=""/></event>
<property name="all"/>
</log>
Полный журнал растет быстро, держите его включенным только на время одного воспроизведения. Читать нужно хвост лога процесса (<каталог журнала>\1cv8_<PID>\...log) перед строкой OSException.
У нас хвост выглядел так: лавина серверных вызовов IFolderFileHost.open, сотни тысяч обращений, затем Outgoing connection closed, затем Access Violation. Конфигуратор через сервер читал и сравнивал всю конфигурацию и не выдерживал объема обращений. Мы проверили и отбросили остальные версии: конфигуратор x64 и свободная память есть, диск в порядке, DBCC CHECKDB чистый, модель EDT валидна. Вывод неприятный, но полезный: путь применения конфигурации через клиента к большой серверной базе не выдерживает объем, и чинить надо путь, а не код.
Решение: реструктуризация силами сервера
Пакетный конфигуратор с ключом -Server у /UpdateDBCfg перекладывает реструктуризацию на серверную сторону, на rphost. Клиентский агент, который падал, из цепочки выпадает.
"C:\Program Files\1cv8\<версия>\bin\1cv8.exe" DESIGNER /S "srv:port\Ref" /N"user" /P"pass" /UpdateDBCfg -Server /Out "C:\tmp\updatedb.log" /DisableStartupDialogs /DisableStartupMessages
Сервер доводит перестройку до конца, даже если клиент-конфигуратор падает на финальном обмене. Такой вылет в конце косметический, база при этом обновлена. Проверять успех нужно не по поведению окна, а по факту: повторный запуск говорит, что база не требует обновления, а объекты видны в Предприятии после перезапуска сеанса (командный интерфейс кешируется).
Пустой файл /Out здесь норма: туда пишутся ошибки, а текст появляется, только когда была реструктуризация.
Запускать 1cv8.exe лучше через PowerShell Start-Process. Мы запускаем конфигуратор из сессии ИИ-агента, и прямой вызов из bash там молча завершается с кодом 1, не создавая лог /Out. Тот же вызов через Start-Process -Wait -PassThru отрабатывает нормально:
$exe = "C:\Program Files\1cv8\<версия>\bin\1cv8.exe"
$a = @('DESIGNER','/S','srv:port\Ref','/N','user','/P','pass',
'/UpdateDBCfg','-Server','/Out','C:\tmp\updatedb.log',
'/DisableStartupDialogs','/DisableStartupMessages')
$p = Start-Process -FilePath $exe -ArgumentList $a -PassThru -Wait
$p.ExitCode
Если и это не помогает, остается обходной путь, который работает всегда, но дольше: выгрузить базу в .dt (/DumpIB), загрузить в файловую базу (/RestoreIB), обновить конфигурацию там, локально и без серверных обращений, выгрузить обратно и загрузить в серверную базу.
Протокол 9 сентября по шагам
Второй случай пришелся на сентябрь, и его мы записали поминутно. После аварийного завершения сервера обновление из EDT упало с «Неизвестный объект метаданных - Report.<Имя>.Template.<Макет>». Объект в проекте был цел: файлы на месте, XML читается, запись в составе есть, ошибок проекта нет. Значит, рассогласован снимок EDT, и ломать проект незачем.
Шаг 1. Полная выгрузка. Обновление с fullUpdate=true. Клиент MCP отвалился по своему таймауту раньше, чем все закончилось, но это не отмена, работа продолжается. Хронология из логов: в 07:38 вызов принят, в 07:42 началась «Загрузка конфигурации в информационную базу», в 09:04 «Обновление конфигурации базы данных», то есть конфигурация принята и пошла реструктуризация. В 09:07 DesignerDisconnectException, «Потеряно соединение с агентом конфигуратора». Вызов завершился ошибкой через 89 минут.
Здесь важная деталь: к моменту падения конфигурация уже загружена в основную. Начинать полную выгрузку заново не нужно, достаточно завершить обновление базы.
Шаг 2. Убедиться, что нагрузка своя. Здесь легко потерять час. На машине три кластера: 8.3.27.1719 (regport 1541), 8.3.27.1859 (regport 3541) и наш 8.5.1.1507 (regport 5541). Три rphost кластера 1541 грузили по 3-4 ядра, и казалось, что сервер вот-вот доведет перестройку. Это была чужая нагрузка. Наш rphost был ровно один и все это время простаивал.
Свои процессы опознаются по версии платформы в пути и по порту регистрации:
Get-CimInstance Win32_Process -Filter "Name='rphost.exe' OR Name='ragent.exe' OR Name='rmngr.exe'" |
ForEach-Object {
$v = if ($_.ExecutablePath -match '8\.\d+\.\d+\.\d+') { $matches[0] } else { '?' }
[PSCustomObject]@{ Имя=$_.Name; PID=$_.ProcessId; Родитель=$_.ParentProcessId; Версия=$v
Аргументы=$_.CommandLine }
} | Sort-Object Версия | Format-Table -AutoSize
Свои те, у кого версия совпадает с версией базы, а -regport равен порту вашего кластера. rphost привязаны к своему ragent через ParentProcessId. Загрузка процессора без такой проверки не значит ничего.
Если нужно понять, идет ли на сервере запрос к СУБД, помогает rac session list по своему кластеру: поля duration-current и duration-current-dbms показывают, чем занят сеанс. У кластера 8.5 RAS у нас не запущен постоянно, его поднимаем на время (ras.exe cluster --port=5545 localhost:5540).
Шаг 3. Пакетная перестройка. Команда из предыдущего раздела, через Start-Process. Первый запуск почти наверняка упрется в блокировку:
Ошибка блокировки информационной базы для конфигурирования.
С этой информационной базой уже работает конфигуратор:
компьютер: <хост>, сеанс: N, начат: <время>, приложение: Конфигуратор
Шаг 4. Снять агент, который EDT поднял сам. Причина блокировки неочевидная: EDT заново поднимает агент конфигуратора без всякой операции. Агент упал в 09:07, а в 09:31:43 на той же базе появился новый процесс 1cv8.exe DESIGNER. За все время он потратил 6,7 секунды процессора, то есть ничего не делал, но держал монопольный доступ.
Get-CimInstance Win32_Process -Filter "Name='1cv8.exe'" |
Where-Object { $_.CommandLine -match 'DESIGNER' -and $_.CommandLine -match '<база>' } |
ForEach-Object { "PID $($_.ProcessId)"; Stop-Process -Id $_.ProcessId -Force }
Снимать безопасно, когда панель «Состояние» в EDT пуста и в .metadata/.log нет активной операции. Такой агент просто держит сессию. После этого повторяем шаг 3.
Базу может держать не только агент. В другой раз обновление не давало сделать зависшее регламентное задание БСП «Извлечение текста»: оно встало внутри извлечения файла с открытой транзакцией, и соединение с SQL «спало» двое с половиной суток. Штатно, через rac session terminate, этот вызов не снимался, помог только перезапуск rphost в окно без пользователей. Перед таким перезапуском посмотрите, кто еще работает в этом процессе: там может оказаться чужой конфигуратор.
Шаг 5. Проверка. В файле /Out:
Обновление конфигурации базы данных
Обработка структуры базы данных...
Принятие изменений...
Обновление конфигурации базы данных успешно завершено
Перестройка заняла 6 минут против 89 минут безрезультатной работы через EDT. Честности ради: сравнение не вполне ровное. Большую часть из 89 минут EDT загружала конфигурацию, и пакетный запуск стартовал, когда она уже была принята. Но сама реструктуризация через агента не дожила и до трех минут, а через сервер прошла целиком.
Что после этого с EDT
EDT о пакетном обновлении не знает, и get_applications продолжит показывать INCREMENTAL_UPDATE_REQUIRED. На работу базы это не влияет, но при следующем обновлении из EDT появится окно «Изменения конфигурации информационной базы». Отвечать Override (externalInfobaseChanges=override): проект перезаписывает базу. Никогда Import: он затянет состояние базы в исходники проекта и затрет вашу работу.
Когда виновата сама база
Аппаратный сбой (скачок питания и подобное) может оставить базу поврежденной. Симптомы похожи на описанные выше: «неизвестный объект», падения реструктуризации, плюс новое: Нарушено условие уникальности данных или duplicate key при создании индекса.
Здесь две проверки, и нужны обе, потому что видят они разное. DBCC CHECKDB('<база>') WITH NO_INFOMSGS, ALL_ERRORMSGS проверяет физическую целостность на стороне SQL, пустой вывод означает ноль ошибок. «Тестирование и исправление информационной базы» в конфигураторе проверяет логическую и ссылочную целостность 1С и переиндексирует таблицы. DBCC этих проблем не видит, а тестирование часто само разблокирует реструктуризацию.
Дубль уникального ключа исправляется только средствами 1С. Например, у двух элементов справочника оказался одинаковый код, и уникальный индекс при реструктуризации не создается. Пока обновление не применено, база в режиме Предприятия работает на прежней конфигурации, поэтому дубли можно найти обычным запросом:
ВЫБРАТЬ
Спр.Код КАК Код,
КОЛИЧЕСТВО(*) КАК Количество
ИЗ
Справочник.<Имя> КАК Спр
СГРУППИРОВАТЬ ПО
Спр.Код
ИМЕЮЩИЕ
КОЛИЧЕСТВО(*) > 1
Дальше одному из элементов меняем код в форме или обработкой, лишний элемент помечаем на удаление, снова запускаем «Тестирование и исправление» и повторяем обновление. Таблицы базы напрямую через SQL не правим: такая правка обходит платформу (регистрацию изменений для обмена, версии объектов, кеши) и может повредить базу сильнее, чем исходный дубль. И, как перед любым исправлением данных, сначала свежий бэкап.
Порядок диагностики

Порядок, к которому мы пришли. Дешевые проверки стоят сверху, и пропускать их ради «сразу посмотреть журнал» не стоит: первые два пункта закрывают большую часть случаев за минуты.
- Модель EDT чистая? Ревалидация и ошибки проекта. На БП в толстом клиенте тысячи фоновых «не определена переменная», они не ваши: смотрите прирост по своим объектам.
- Объект есть в
Configuration.mdo? Особенно если объект создан скриптом, а не конструктором. - База цела? DBCC CHECKDB и тестирование и исправление.
- Ресурсы. Диск под базу, журнал и tempdb, память, разрядность конфигуратора.
- Почему упал процесс? Журнал Windows и техжурнал нужной версии платформы.
- Нагрузка своя? При нескольких кластерах на машине сначала опознать свои
rphostпо версии и-regport. - Кто держит базу? Агент EDT, который поднялся сам, зависшее фоновое задание.
- Применение. Полная выгрузка вместо инкремента,
/UpdateDBCfg -Serverили обход через файловую базу.
После любого обновления перезапускайте сеанс 1С: он кеширует конфигурацию и командный интерфейс.
Если обновление не падает, а висит часами с загрузкой ядра на 100 % и не трогает SQL, это, скорее всего, другая история: порядок блоков в правах ролей. Ей посвящена отдельная статья: Четыре дня зависшего обновления конфигурации: порядок блоков в Rights.rights.
Главное, что я вынес из этих двух аварий: клиент конфигуратора и агент EDT оказались самым слабым звеном цепочки, а не сервер и не база. Сервер довел за 6 минут то, на чем клиент 89 минут падал. Поэтому на большой серверной базе после любого сбоя я бы начинал не с повторного нажатия «Обновить», а с проверки своих процессов и сразу с пакетного -Server.
Если у вас реструктуризация падала по другой причине, или -Server не помог, напишите в комментариях: версию платформы, СУБД, что было в журнале Windows и в хвосте техжурнала. Таких случаев в открытом доступе мало, а каждый разобранный экономит кому-то день.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.