Восстанавливаем убитую базу 1C

Наверняка никому из моих постоянных читателей тема этой статьи не будет интересной, но абсолютно точно люди из интернетов будут находить её и радоваться, если она им поможет.

Так вот, прихожу на обед, а Наташа сидит с явным выражением шока на лице. У Наташи случился «Не удалось найти файл v8srvr://dbeng8/f0577CFD0/Config/version.new» на рабочей базе бухгалтерии одной огромной организации. Резервным копиям десять дней, десять кровавых рабочих дней с шести утра до полуночи, и каждый утраченный в рабочей базе документик словно вырванный зуб.

В Интернетах по запросу «В моём 1C случилась беда» вываливается полтора форума, где вместо решений проблемы все пишут «У меня также!!! Помогите мне тоже!!!!» Вот здесь, например.

Вообще, в нашей семье роль программиста 1C выполняет Наташа, а не я, но здесь сразу стало понятно, что пора сдувать пыль со своего диплома о высшем образовании и подключаться. А Наташу нужно отправить прыгать по весенним лужам.

Так вот, в чём проблема:
1C 8.2 может быть построен на базе SQL сервера (мне было бы проще, в таком случае) или на базе файловой системы (и у нас именно такой случай). Вот в этом втором случае вся конфигурация и данные хранятся в огромном файле с расширением 1CD, и что там внутри с первого раза не очень понятно.
И сегодня выяснилось, что этот огромный файл не хочет работать.

Первонаперво я сделал резервную копию убитой базы. Чтобы мои хирургические вмешательства не уничтожили то немногое, что осталось.

Встроенная утилита chdbfl, которая идёт с 1C, сообщила мне, что данные как-то очень уж безвозвратно попортились, и она не готова мне помочь. Ну ладно, мы и не думали, что будет просто.

Далее в интернете я обнаружил чудную программу Tool_1CD. Она открывает этот самый большой побитый файл и читает всё, что в нём скрыто. Утилита прочитала базу без проблем, с помощью неё я сразу же сохранил конфигурацию в формате cf на всякий случай. Ну и вот, он, этот самый негодяйский файл version.new.

Видим, что с файлом всё в порядке, он себя хорошо чувствует.
Судя по всему, вся проблема в том, что этого файла быть там не должно. Вот смотрим этой же утилитой живую конфигурацию:

Действительно, у нормальных ребят таких файлов нет. У нормальных ребят файл versions не имеет никакого расширения.

Увы, программа Tool_1CD не умеет редактировать базу, она только может подсказать, что в ней скрыто.

Вам наверное не очень понятно, почему я называю versions файлом, и как так может быть, что в файле конфигурационной базы скрыты другие файлы. Да, мой юный друг, это вполне модная затея — хранить в одном файле массу других файлов. Вспомни архивы на своём компьютере, там именно так. Вот и база 1C представляет из себя кучу таблиц, и в ячейках этих таблиц между делом могут храниться целые файлы. Если твой 1C собран на базе SQL — там будет ровно такая же фигня, и благодаря открытости формата SQL ты можешь подключиться консолью БД и увидеть всё своими глазами.

Так вот, в таблице CONFIG у нас обнаружились непонятные файлы, и судя по всему проблема в них. Разглядывание глазами привело меня к мысли, что в этой таблице находится конфигурация базы данных. А сами документы находятся где-то в другой таблице. Наташа поклялась мне, что с момента резервной копии она не очень существенно меняла конфигурацию, и структура данных не поменялась.

Вся идея восстановления в моём представлении стала заключаться в том, чтобы взять таблицу CONFIG из резервной копии и запульнуть её в повреждённую базу.

Так я и сделал.

Вот здесь автор программы Tool_1CD благородно раскрыл примерный формат файла 1CD. Это очень помогло. Спасибо тебе, автор программы Tool_1CD. И программа хорошая, и формат файла мне пригодился.

Для того, чтобы комфортно ковыряться в бинарных файлах, мужчине нужно иметь в доме шестнадцатиричный редактор. Я не пользовался ничем подобным уже лет семь. Стал скачивать с интернета эти самые редакторы: Ultraedit, Hiew, 010 Editor — а они все платные! Представляете, в яндексе уже стало проблематичным найти нормальную взломанную версию шестнадцатиричного редактора, куда катится этот мир?
В итоге поставил HxD, он сделал всю грязную работу.

Вот люди на форуме пишут свои рецепты:

1. Открыть базу с помощью утилиты tool_1CD.exe определяем размер таблицы CONFIG или CONFIGSAVE в базах. 
2. С помощью текстовых редакторов находим это место в базе. можно с помощью TotalCommander разбить файл, чтобы таблица CONFIG могла попасть в одну из частей. Затем отредактировать, Полученные файлы. 
3. Редактируем кусочек текста между {«Folder»,»Config», и {«Folder»,»ConfigSave», — это конфигурация, надо заменить на кусок из работующей конфигурации. 
4. Собираем TotalCommander-ом, сохраняем, даже если будет жаловатся(на crc).

А потом другие люди это пробуют сделать и пишут вот такие комментарии:
Но открыв в редакторе файл 1CD и сделав поиск по названию таблицы, я ничего не нашел. Больше ничего в голову не идет, поэтому решил спросить вашего совета.

Сроки горят бухгалтер в истерике. Пробовала по вашим советам скачать программу Tool_1CD, скачала….открыла….посмотрела….поняла что ничего не поняла. Одна надежда на сдешних чудотворцев…..

Подскажите, пожалуйста, уважаемые — КАК КОРРЕКТНО заменить таблицу CONFIG в битом 1CD? WinHEX’а не боюсь, со смещениями и прочим вроде разбираюсь — но что-то постоянно ускальзывает в этой задаче от меня. Поможете?

1. открывал winhex’ом мертвый 1CD, открывал живой параллельно (из типовухи или старого архива) 
2. находил сегмент начала таблицы CONFIG (0x00009000) в обоих файлах 
3. находил окончание таблицы (проще всего по началу CONFIGSAVE) в обоих файлах 
4. копировал из нормального файла в битый (заменяя битое на нормальное). но видимо что-то не учитываю постоянно — формат файла корежится. и даже chdbfl.exe ругается на битость 

Ну да, там всё оказалось не совсем тривиально.

Дальше статья будет совсем скучной, если вы не собираетесь прямо сейчас восстанавливать какой-нибудь 1CD файл, то можете не читать 🙂

Итак, открываем HxD и начинаем смотреть. Юзернейм awa сообщает, что правильный файл базы будет по размеру кратен 4096 байтам (в шестнадцатеричном — 0x1000) и размер базы указан в самом начале файла. Вот как хранится размер:

А вот так мы можем посмотреть, сколько на самом деле занимает файл:

Видим, что никакого обмана: размер файла 1FA31000, судя по тому, что в конце числа у нас три нуля, оно действительно кратно 0x1000. Ну, и в заголовке файла мы видим 31 FA 01 00 — если прочитать в другую сторону, получается 1FA31. Размер указан в блоках по 0x1000 байт — добавляем три нуля и получаем нужное значение.
Кстати, запомните этот трюк про шестнадцатеричное умножение на 0x1000. Просто дописываешь три нуля в конце и получаешь нужное число. Пригодится в жизни.

Дальше смотрим. Нам нужно найти таблицу CONFIG. Если просто открыть файл текстовым редактором и сделать поиск, то фраза не находится. Почему? Потому что в файле все строки хранятся в UNICODE и поэтому выглядят вот так:

Поэтому, если вы пользуетесь просмотрщиком из Total Commandera, переключите кодировку в Юникод и он вам всё найдет.
Ребята на форуме оказались правы. База Config действительно начинается на смещении 0x9000
Полнотекстовым поиском я также нашёл базу ConfigSave.

Оно оказалось на смещении 0C782000
Проанализировав целую базу, я увидел, что в ней таблица Config ожидаемо находится на 9000, а вот ConfigSave — на 07С83000. То есть, в старой базе блок Config длиннее аж на 0x1000 байт.
Ну, это сразу и навело меня на размышления. Наверняка если я вставлю в новую базу более длинный кусок, всё там посдвигается и 1C сойдет с ума.
Попробовал: удалил все байты с 0x9000 по 0x0C782000 и потом вставил из целой базы. Сохранил, запустил — стало ещё хуже: 1С говорит что база ему совсем не нравится, chdbfl сообщил, что данным пришёл конец, а Tool_1CD выдал кучу ошибок. И в этих ошибках написано: неправильное смещение блока C77F. И таблица Config открывается. Это означает, что пересадка таблицы Config прошла успешно, но вот всё остальное сломалось. Переходим к блоку C77F (0x0c77f000) — и там действительно нет  начала блока. А в документации по 1CD мы выяснили, как должен выглядеть правильный блок. Вот так:

Ну, значит, действительно — все данные в файле сместились и это нарушает целостность данных.
Продолжаем разбираться, и читаем у awa про корневой объект. Оказывается, внутри файла 1CD есть блок, в котором хранятся смещения всех таблиц. Соответственно, смещение таблицы Config не меняется и поэтому она открывается утилитой верно, а все остальное съезжает. И нужно что-то с этим делать. Я нашёл этот корневой объект на смещении 0x4000 :

Вот полюбуйтесь, как выглядит этот корневой объект на целой и сломанной базе. Начинается он с текста ru_RU, затем ниже мы видим значения 00 00 05 CD (всё хранится в обратную сторону, не забыли?) — эти значения одинаковые в обоих файлах — количество таблиц. Дальше идёт ещё одна одинаковая запись 00 00 00 05. Так вот, это и есть начало блока таблицы Config — 5000, а не 9000. Я сравнил отрезки с 5000 до 9000 в двух файлах (старом и новом) и там есть какая-то разница, в которую я не стал вникать. Поэтому я пришёл к мысли, что и копировать блок Config надо не с того места, где в файле написано слово Config, а именно со смещения 0x5000.
Далее в корневом объекте мы видим записи 00 00 C7 7E и 00 00 С7 7F — это как раз начало блока ConfigSave. Видите — отличаются ровно на 1000, но тоже не указывают ровно на то место, где находится слово ConfigSave.

Теоретически, усидчивый парень может запихнуть из рабочей базы в нерабочую блок Config, а затем поправить все смещения. Но я поленился так делать. Я решил попробовать каким-то образом сравнять размеры блоков Config, чтобы ничего не сдвигалось. И вот что я сделал:
1. Я скопировал старый Config в разбитую базу.
2. В корневом объекте исправил 00 00 C7 7E на 00 00 C7 7F потому что блок Config стал длиннее и следующая таблица сдвинулась.
3. Перешёл на 00 00 C7 7F и стал смотреть:

Вот у нас начало блока и далее — адрес смещения, где должна начинаться таблица. Перехожу к этому смещению (C782000) и там буквально экраном ниже начинается таблица ConfigSave. Но между текущим блоком и следующим методом прокручивания обнаруживается какой-то непонятный пустой блок:

И в этот момент я подумал: в таблице ConfigSave хранится промежуточная конфигурация. Наверное, ничего страшного не произойдет, если она будет не совсем целая.
Поэтому я совершенно не переживая взял и удалил целый блок с 0C780000, ровно 0x1000 байт — до следующего блока.
Всё сдвинулось обратно, и смещения стали совпадать с тем, что указано в корневом объекте.

Ну, тогда я это сохранил и запустил 1C. Я был абсолютно уверен, что все заработает и оно заработало.
Из конфигуратора я тут же сделал резервные копии данных.
Затем я на всякий случай проверил базу через chdbfl, она ругнулась на таблицу ConfigSave, но сообщила, что всё починено.

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

Удачи.

Восстанавливаем убитую базу 1C: 11 комментариев

    1. я сначала тоже хотел написать десять лет, но все таки стоит признать — до пятого курса писал на ассемблере, а это не так уж и давно было

    1. чтобы оценить масштаб катастрофы, скажу, что у нас во всём городе по моим данным правильно копируется только Сибпромстрой ЛК, у них даже стриммер есть

      в 1С на базе файловой системы, насколько я знаю, сложно сделать инкрементальную копию, поэтому приходится всю эту многогигабайтную базу копировать — каждый день не накопируешься.

      1. Честно говоря, я не совсем в теме, но есть же сторонние средства, например, handy backup по вполне приемлемой цене. А вообще, при определенном размере предприятия потеря информацию страшнее затрат на ее защиту.

        1. ну тоже самое можно сказать про пожарную безопасность 🙂

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

          все знают, что нужно копироваться каждый день, но это непросто на деле.

  1. Спасибо за статью. Помогла в смысле поиска софта для восстановления файла 1CD. Рекомендую на будущее программу библиотеку 1CDLib (http://infostart.ru/public/166557/). Ею восстановил свою убитую базу.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *