Формат файлов выгрузки DT

29.05.23

База данных - Инструменты администратора БД

Описание формата файлов выгрузки DT, может стать основой для разработки средств восстановления данных

Так получилось, что форматы файловых баз 1CD и файлов конфигураций CF достаточно подробно описаны, и сделано множество утилит для работы с ними. Разумеется, для рабочих целей их не используют, но иногда они незаменимы для восстановления поврежденных баз. С помощью Tool1CD уважаемого awa (светлая ему память) было восстановлено бесчисленное количество баз.

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

Внимание! Комментарии вида "А какой смысл в поле 8 описания таблицы в DBSchema" из чистого любопытства не приветствуются - что знал то описал. Наоборот, содержательные дополняющие комментарии приветствуются.

Не секрет, что файл содержит заголовок 1CIBDmpF (очевидно сокращение от 1C Informational Base Dump File - файл выгрузки информационной базы 1С, внезапно), ещё один символ - 1, 2 или 3 - версия формата, а дальше идут сжатые алгоритмом Deflate данные.

 

 

Для старого формата "1", который использовался в платформе 8.0 и 8.1, после распаковки структура данных была почти очевидна. Распаковка давала любимую 1С скобочную запись с описанием конфигурации и данных.

 

 

Форматы 2 (от платформы 8.2) и 3 (платформа 8.3) по сути повторяют эту идею, но распаковка даёт "странное" бинарное представление данных. Это - бинарное представление того скобочного формата, которое использовалось в версии 1.

Разобраться с этим бинарным форматом мне помогли исходники Tool1CD от awa. В архиве оказалась заготовка конвертора из бинарного представления обратно в текстовый скобочный.

Итак. Этот бинарный вид - эквивалент скомпилированной скобочной записи. Далее я буду делать вид что всё конвертируется именно в текстовую скобочную запись, хотя есть все основания считать что это просто эквивалент, и 1С промежуточный текстовый формат при распаковке базы не использует. Основа данных - байты-тэги, которые описывают формат следом идущих данных. Основных тэгов 32, с нумерацией от 0 до 0x1F, в младших 5 битах байта. Ещё есть 3 дополнительных тэга, не образующих отдельных байт, а представленные битами в байте-тэге, комбинируются с одним из базовых тэгов. Это бит 6 (0x20) - "закрывающая скобка, закрытие списка", бит 8 (0x80) - "запятая, разделитель значений в списке", и бит 7 (0x40) - "открывающая скобка, начало списка". Обрабатываются они именно в этом порядке.

Таким образом байт тэга обрабатывается таким образом:

1. если в байте тэга установлен бит 6 - ставим закрывающую скобку
2. если в байте тэга установлен бит 8 - ставим запятую
3. если в байте тэга установлен бит 7 - ставим открывающую скобку
4. выделяем младшие 5 бит и обрабатываем тэг оттуда.

Тэги:

0x00 - NOP, отсутствие операции
0x01 - 0x0A - "цифра 0-9", выводим цифру. 0x01 - выводим 0, 0x0A - выводим 9
0x0B - байт uint8. Надо считать следующий байт и вывести (как число)
0x0C - "минус" байт. Надо вывести знак минус и считать следующий байт как число
0x0D - слово (uint16). Надо считать следующие число из следующих 2 байт и вывести как число. Младший байт первым.
0x0E - "минус" слово. Аналогично предыдущему, только с минусом
0x0F - двойное слово uint32. Считать число из 4 байт и вывести
0x10 - "минус" двойное слово. Аналогично, с минусом
0x11 - int64 - 8-байтовое число. Вероятно со знаком.
0x12-0x14 - неизвестно.
0x15 - GUID. Считать 16 байт и вывести. В формате "почти MS" - <uint32>-<uint16>-<uint16>-<uint8><uint8>-<uint8*6>
0x16 - "отмена кавычек". По умолчанию строки выводятся в двойных кавычках, но если перед строковым тэгом будет "отмена кавычек" - значение выводится без кавычек. После вывода строки признак сбрасывается на значение по-умолчанию, "в кавычках"
0x17 - Юникод-строка (UTF-16), до 255 символов. Надо прочитать 1 байт длины, и прочитать указанное число двухбайтовых символов.
0x18 - Юникод-строка (UTF-16), до 65535 символов. Длина указывается 2-байтовым числом.
0x19 - Юникод-строка (UTF-16), до int64 символов. Длина указывается 8-байтовым числом.
0x1A - ANSI-строка или двоичные данные, до 255 символов. Надо прочитать 1 байт длины, и прочитать указанное число символов. Если присутствуют символы с кодами меньше 0x20 или больше 0x7F - считать двоичными данными (выводить шестнадцатеричные значения), если была отмена кавычек - вывести строку как есть, иначе выводить в двойных кавычках
0x1B - ANSI-строка или двоичные данные до 65535 символов. Длина задаётся uint16 - двухбайтовое целое.
0x1C - ANSI-строка или двоичные данные, до int64 символов. Длина задаётся uint64 - 8 байт.
0x1D-0x1F неизвестно.

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

Это утилита для командной строки. Командой -unpack распаковывает сжатый поток, команда -dump распаковывает и выводит текстовое представление в скобочной записи, -scan проводит сканирование потока тэгов на предмет ошибок.

Небольшое отступление. В базе обязаны быть таблицы Config/ConfigSave для сохранения конфигурации базы, ConfigCas/ConfigCasSave для расширений (начиная с платформы 8.3), Params и Files для служебных данных (критически важно значение DBNames таблицы Params - соответствие идентификаторов конфигурации таблицам и полям базы), DBSchema - описание физической структуры таблиц базы данных. V8Users - список пользователей (начиная с платформы 8.1), и некоторые другие.

 

 

Что же содержат распакованные данные? Это список объектов, первым элементом списка которых идёт строка с типом объекта.

В формате 1 это были Folder и Database
В формате 2 текстовое заменили на бинарное. Появился объект Users. С платформы 8.2.14 стали появлятся дополнительные "флаговые" объекты CompatibilityMode, CustomFlag
В формате 3 в платформа 8.3.21 заменила Users на UsersSpr, появился PasswordPolicies

Folder описывает служебные таблицы со структурой как у таблицы Config. В списке вторым значением после Folder идёт строковый параметр - имя служебной таблицы: Config, ConfigSave, ConfigCAS, ConfigCASSave, Files, Params, DepotFiles

Все они имеют структуру:

{"FILENAME","NVC",0,128,0,"CI"},
{"CREATION","DT",0,0,0,"CS"},
{"MODIFIED","DT",0,0,0,"CS"},
{"ATTRIBUTES","N",0,5,0,"CS"},
{"DATASIZE","N",0,10,0,"CS"},
{"BINARYDATA","I",0,0,0,"CS"}

Платформа 8.3 добавила в базу поле PartNo для разбиение больших объектов на части, но в выгрузке его нет, всё склеивается в один целый объект

Users или UsersSpr распаковывается в таблицу V8Users со списком пользователей.

Users содержит следующие поля:

{"ID","B",0,16,0,"CS"},
{"NAME","NVC",0,64,0,"CI"},
{"DESCR","NVC",0,128,0,"CI"},
{"OSNAME","NVC",1,128,0,"CI"},
{"CHANGED","DT",0,0,0,"CS"},
{"ROLESID","N",0,10,0,"CS"},
{"SHOW","L",0,0,0,"CS"},
{"DATA","I",0,0,0,"CS"},
 

UsersSpr добавляет "недостающие" поля, которые платформа раньше восстанавливала по данным:

{"ID","B",0,16,0,"CS"},
{"NAME","NVC",0,64,0,"CI"},
{"DESCR","NVC",0,128,0,"CI"},
{"OSNAME","NVC",1,128,0,"CI"},
{"CHANGED","DT",0,0,0,"CS"},
{"ROLESID","N",0,10,0,"CS"},
{"SHOW","L",0,0,0,"CS"},
{"DATA","I",0,0,0,"CS"},
{"EAUTH","L",1,0,0,"CS"},
{"ADMROLE","L",1,0,0,"CS"},
{"USSPRH","N",1,10,0,"CS"}
 

Database описывает физическую структуру таблиц базы данных (это описание хранится в таблице DBSchema) и далее сами данные таблиц в порядке их следования в DBSchema.

Каждая таблица описывается отдельным списком, первый элемент - число 0, далее список объектов - строк таблицы. Сначала идёт флаг - 0 если значение отсутствует (null) или 1 если следом идёт фактическое значение. Значения типа "B" (binary) описываются не одним значением а объектом, в котором первым элементом списка идёт число 0, а дальше двоичные данные. Данные могут разбиваться на несколько частей запятыми, их следует склеивать. Некоторые частные случаи платформа оптимизирует, например пустая строка может быть представлена числом 0, или один байт двоичных данных может быть представлен не тэгом 1A "строка" а тэгом 0B "байт". Одиночные символы тоже могут быть закодированы тэгом 0B с кодом символа.

Описание таблиц "пользовательских" данных (туда же попадают и таблицы типа ExtensionsInfo, SystemSettings и подобные) восстанавливаются из DBSchema.

DBSchema - объект, первым элементом идёт число 0, дальше вложенный объект со списком описания таблиц. Первым элементом списка идёт количество объектов-описаний, далее сами описания. Каждый объект описания таблицы начинается с имени таблицы, далее идёт символ - "тип" таблицы, "N" - обычная и "I" для подтаблиц (табличные части справочников, документов и т.д.). Далее идёт "номер" таблиц, замет строка - имя родительской таблицы, затем объект - список полей, затем объект - список "подтаблиц", затем список индексов таблицы, неопознанные поля, среди которых два списка - предположительно список полей - для использования "разделителей" данных в режиме Фрэш.

Описание поля таблицы - "логическое" имя поля, признак может ли поле содержать Null, список типов и поля "неопознанного" назначения

У поля может быть несколько типов, и итоговый набор физических полей и их имён нужно строить по имеющимся данным. Для каждого типа поля создаётся минимум одно поле физической таблицы. Если для поля создаётся несколько физических полей к имени таблицы добавляются суффиксы с именами типов.

 

 

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

Если в длине поля установлен старший бит 0x80000000 - это поле переменной длины.

Коды типов:

  • N - число.
  • R - ссылка. К имени добавляется суффикс RREF, фактически это тип B(16). Если отсутствует строка с описанием таблицы - то значение может ссылаться на различные объекты в базе, и физически создаётся дополнительное поле с суффиксами TREF (тип B(4)) для номера объекта на который идёт ссылка.
  • S - строка. Если длина 0 - это поле неограниченной длины (memo), которое в 1CD хранится в BLOBе
  • B - двоичные данные. Если длина 0 - в 1CD значение попадёт в BLOB. Если длина 16 - это ссылка. 
  • L - логическое, true/false, 1/0
  • V - "версия" записи, физически в DT не присутствует.
  • T - Дата-время. Хранится в десятых долях количества миллисекунд от 00:00:00 01.01.0001
  • E - присутствует если поле составного типа, физически это B(1), добавляет префикс _TYPE, к остальным физическим полям добавляется суффикс _<КодТипа>, а ссылочные поля получают двойные суффиксы _RTREF и _RRREF

Для подчиненных таблиц неявно добавляются поля _ИмяРодительскойТаблицы_IDRREF (R) и _KEYFIELD (B(4)), а так же поля-разделители.

Фактический состав полей предлагаю сверять с физической структурой базы в Tool1CD.

Описание индекса - имя, предположительно признак уникальности индекса, объект-список полей входящих в индекс (состав списка - число входящих полей и их имена), значения неопределенного назначения. Похоже что некоторые поля добавляются неявно, так же некоторые индексы тоже создаются неявно, т.е. их описание не присутствует в DBSchema.

Недавно мне на восстановление дали очень занятный файл выгрузки. Это была единственная копия базы, и она не загружалась с ошибкой формата потока. Оказалось - 1С при выгрузке записала немного мусора в область данных таблицы Config. Хотя сжатие данных было целым, что уже хорошо.

Обнаружилось это с помощью той утилиты в режиме dump

Смог базу вылечить, распаковав (unpack), в шестнадцатеричном редакторе вырезал поврежденный кусок, упаковал обратно, и выгрузка загрузилась. Повреждение конфигурации восстановил загрузив эталонную конфигурацию в базу.

формат DT

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    126652    685    389    

738

Infostart PrintWizard - создание и редактирование печатных форм в 1С 8.3

Пакетная печать Печатные формы Инструментарий разработчика Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

Инструмент, позволяющий абсолютно по-новому взглянуть на процесс разработки печатных форм. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и "прозрачность" разработки, а также навести порядок в многообразии корпоративных печатных форм.

18000 руб.

06.10.2023    8342    24    6    

45

Автоподбор ролей для профилей и групп доступа в любых типовых базах 1С УТ 11, КА 2, ERP2, Розница 2/3, УНФ 16/3, БП 3, ЗУП 3 и подобных (УФ, Платформа 8.3.14+)

Инструменты администратора БД Роли и права 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 15.12.2023, версия 1.1.

14400 руб.

06.12.2023    3730    19    1    

41

Infostart УДиФ: Управление данными и формами 1С

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 руб.

10.11.2023    4697    12    2    

38

SALE! %

PowerTools

Инструментарий разработчика Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

3600 2280 руб.

14.01.2013    178885    1084    0    

862

Ускоренное проведение документов (x4), устранение ошибок 60/62 счетов и зачет авансов (Бухгалтерия 3.0)

Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).

14400 руб.

29.04.2020    28132    83    146    

61

Бустер Конвертации данных 3 (Infostart Toolkit)

Инструментарий разработчика 8.3.14 1С:Конвертация данных Россия Платные (руб)

Расширение для конфигурации “Конвертация данных 3”. Добавляет подсветку синтаксиса, детальную контекстную подсказку, глобальный поиск по коду.

15000 руб.

07.10.2021    15083    3    12    

37

"Менеджер потоков 2.1": УПП: "Восстановление партий"

Инструменты администратора БД Платформа 1С v8.3 1С:Управление производственным предприятием Россия Бухгалтерский учет Управленческий учет Платные (руб)

Как оптимизировать то, что, считалось, не поддается оптимизации? Как повысить доступность базы данных? Как проводить самую «времяемкую» операцию не по паре раз в неделю, а по несколько раз в день*? Ответ есть!

20000 руб.

12.09.2019    11892    5    9    

7
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. it_depDi 29.05.23 23:58 Сейчас в теме
за статью плюс, за FAR плюс с плюсом)
Award; cleaner_it; NiGMa; John_Dow; +4 Ответить
2. maksa2005 534 30.05.23 07:39 Сейчас в теме
Вспомнил далекие 1997-2000 год, когда только познакомился с компом, и там был FAR. Ностальгия
Minotavrik; cleaner_it; +2 Ответить
3. maksa2005 534 30.05.23 07:42 Сейчас в теме
Забыл добавить, что все это конечно классно и авто молодец, но не что так не поможет, как копия за вчерашний день
4. user1854748 30.05.23 08:17 Сейчас в теме
(3) бывает всякое в жизни. Могут позвать помочь, когда уже все пропало. Бывает так что накосячили много лет назад, а ошибка вылезла вчера и все копии с этой ошибкой. Такое бывает когда интерактивно удаляют.
Но думаю чаще всего данный инструмент потребуется при откате версии типовых конфигураций с правками, когда обновление "криво встало".
Поэтому инструмент имеет место быть, копия копией, но вот как быть если ошибка найдена не сразу а через неделю и у тебя 500 человек в базе документы всю неделю вводили. Вот тут подобные велосипеды ой как нужны, по большей части понять как можно исправить не откатываясь.
cleaner_it; Zhilyakovdr; Dach; NiGMa; markers; 7OH; +6 Ответить
5. Pasha1st 838 30.05.23 13:38 Сейчас в теме
Это всё хорошо, но сколько было обращений "а вот у нас есть DT и это единственная копия и она не загружается". Особенно весело когда клиент ловит проблемы в базе, начитается интернетов и решает починить самостоятельно путём выгрузки базы в DT и загрузки обратно. В ту же базу. Без копий. А DT не загружается, но базу уже запорол.
cleaner_it; ZhokhovM; +2 Ответить
6. SerVer1C 763 30.05.23 14:26 Сейчас в теме
(5) Много раз сталкивался с ситуацией, что DT не загружается по причине битого файла (т.е. ошибки в deflate-потоке). Пока такое не удавалось восстановить. Может кто-нить владеет техниками восстановления deflate ?
7. Pasha1st 838 30.05.23 14:31 Сейчас в теме
(6) Это бесполезно, увы. Максимум можно спасти то что до сбоя. С учётом что сначала идёт жирная несжимаемая конфигурация, а данные в хвосте - увы.
cleaner_it; SerVer1C; +2 Ответить
8. frkbvfnjh 787 23.06.23 11:01 Сейчас в теме
Решил попробовать утилиту pfDTTools на выгрузке размером 8,8 Гб - зависла на 8%, ждал 2 часа, но процесс не сдвинулся :(
9. Pasha1st 838 24.06.23 23:31 Сейчас в теме
(8) Файл был не битый? Режим -dump использовали? Не смотрели что получилось в конце выходного файла? Место на диске не закончилось? Программа, конечно, экспериментальная, но на живых файлах зависать не должна.
10. frkbvfnjh 787 26.06.23 05:45 Сейчас в теме
(9) Использовал только -scan, что бы проверить целостность, места на диске и оперативной памяти просто не реально много. Со слов того кто дал этот файл, говорит, что копию успешно развернули. Более мелкие DT проходят проверку успешно. Сейчас попробовал на другой машине - все успешно прошло! Видимо что то с машиной не то...
11. leshik 34 16.11.23 16:01 Сейчас в теме
Протестировал pfDTTools.
Платформа 8.3.23.1912
1)Создал чистую базу (клиент-серверный вариант)
2) Выгрузил в dt
3) Сделал dump с --v3
4) сделал pack этого же файла
- размер отличается
- структура отличается
- новый dt уже dump не проходит;
- при попытке загрузить конфигуратором - ошибка формата потока.
Интерес не академический - из ГРМ выгружается dt с двойными записями в таблице params. Хотел удалить лишнюю.
12. dvsidelnikov 48 23.02.24 21:58 Сейчас в теме
благодаря публикации потихоньку начинаю трогать dt с помощью python:


import zlib
filename_in = r'D:\1C\Базы\какой-то.dt'
file_in = open(filename_in, 'r+b')
if file_in.read(9) == b'1CIBDmpF3':
    deflated_data = file_in.read(128)
    file_in.close()
    decompressobj = zlib.decompressobj(-15)
    decompressed_data = decompressobj.decompress(deflated_data)
    print(decompressed_data)

##b'Z\x11CompatibilityMode\x8f\xc19\x01\x00\xfa\nCustomFlag\x9­a\x12IndexCompatibility\x82\xfa\nCustomFlag\x9a\x07UseMVCC\x­82\xfa\x06Folder\x9a\x06C'
Показать
Оставьте свое сообщение