Устанавливает состав хранимых данных для настройки записи конкретных объектов метаданных. Один и тот же объект метаданных не может быть настроен для использования с разными хранилищами двоичных данных в СоставХранимыхДанныхХранилищаДвоичныхДанных. Если состав хранимых данных содержит объект метаданных, который уже был настроен для использования в другом внешнем или встроенном хранилище двоичных данных, будет сгененировано исключение. Вызов метода требует административных прав в сеансе, в котором все разделители не установлены. Если до вызова метода режим монопольного доступа к базе данных не был установлен, то он устанавливается на время вызова. Если установить монопольный доступ невозможно, будет сгенерировано исключение.
Синтаксис
УстановитьСоставХранимыхДанных(<Состав>)Полное описание, параметры и ограничения
МенеджерХранилищаДвоичныхДанных.УстановитьСоставХранимыхДанных (BinaryDataStorageManager.SetStoredDataContent)
МенеджерХранилищаДвоичныхДанных (BinaryDataStorageManager)
УстановитьСоставХранимыхДанных (SetStoredDataContent)
Доступен, начиная с версии 8.3.26.
Синтаксис:
УстановитьСоставХранимыхДанных(<Состав>)
Параметры:
<Состав> (обязательный)
Тип: СоставХранимыхДанныхХранилищаДвоичныхДанных.
Состав хранимых данных.
Описание:
Устанавливает состав хранимых данных для настройки записи конкретных объектов метаданных.
Один и тот же объект метаданных не может быть настроен для использования с разными хранилищами двоичных данных в СоставХранимыхДанныхХранилищаДвоичныхДанных. Если состав хранимых данных содержит объект метаданных, который уже был настроен для использования в другом внешнем или встроенном хранилище двоичных данных, будет сгененировано исключение.
Вызов метода требует административных прав в сеансе, в котором все разделители не установлены. Если до вызова метода режим монопольного доступа к базе данных не был установлен, то он устанавливается на время вызова. Если установить монопольный доступ невозможно, будет сгенерировано исключение.
Доступность:
Сервер.
Использование в версии:
Доступен, начиная с версии 8.3.26.
Методическая информация
Практические примеры
Свой встроенный binary-store: шесть фаз политики, реальные own пакеты и проверка содержимого
Не формальные setters: полностью собственная новая client-server IB, единственный каталог и шесть собственных4..16KiB payload. Настройки native manager отдельно от ХранилищеЗначения, четыре placement enum, ReadOnly сохраняет IB writes и scoped native database+storage size. Никаких S3/upload/backup/restore/очисток.
Где и как запускать
Полный серверный server-call общий модуль УчебныеДвоичные85. Только own new client-server localhost:1541/ref UUID IB на8.5.1.1343, один actual administrator, one catalog/three exact fields, manual optimized-storage prerequisite;6real own records. CLIENT отдельно full managed form module.
Подготовка
Сначала вручную подготовьте отдельную новую client-server учебную базу на своей локальной VM/своем localhost:1541 cluster, не копию production и не общий сервер. Выберите вариант установленной8.5.1.1343, где native GetBinaryDataStorageAvailability=True. Если он False, урок честно отказывает; не обходите edition/license ограничения.
Сами создайте новый canonical nonzero UUID marker и зарегистрируйте только собственную IB с Ref=Уч85Двоичные_<UUID>. В списке баз задайте строку строго Srvr="localhost:1541";Ref="Уч85Двоичные_<UUID>";. Метод ConnectionString возвращает как зарегистрировано: другой порядок/порт/пробелы/дополнительные параметры даже своего адреса безопасно отвергаются. UUID-marker имени не является realIBUUID; строка соединения никогда не выводится.
Конфигуратор → новая конфигурация → имя УчебныеДвоичные85. Никаких типовых справочников/документов/регистров/внешних источников/подписок/регламентных заданий/общих реквизитов/расширений. Встроенное storage изначально Запретить, native состав пуст, внешних storage0. Код не приспосабливает существующую рабочую базу.
Конфигуратор → Справочники → Добавить → УчебныеПакеты85, Иерархический=Нет, код строковый36, Автонумерация=Нет, наименование100. Добавьте ровно три реквизита: КлючОпыта Строка36, Фаза Число(2,0) неотрицательное, Данные ХранилищеЗначения единственного типа. Табличных частей0, модуль объекта/обработчики записи пустые. Это вручную создаваемая собственная учебная metadata schema, не реально внесенные автором изменения.
Создайте ровно одного собственного реального пользователя IB Уч85Двоичные_<тот жеUUIDmarker>, с уникальным actualIBUUID, административными правами и правом монопольного режима только в этой учебной базе. CurrentUser и списокactualIBUsers проверяются. Никакого privileged impersonation/сервисных пользователей/установленных разделителей нет; права контролирует native платформа.
Обязательная отдельная ручная подготовка администратора: предварительно включите оптимизированное хранение двоичных данных в БД способом, документированным именно для вашей установленной поставки8.5.1.1343/ее средства администрирования. Native SetDataCopiesPlacementMode прямо требует его и иначе выдает ОшибкаСоединенияСБазойДанных. В экспортированной native справке не найден BSLsetter этой настройки; здесь не выдумывается его имя, CLIflag или меню. Если эта prerequisite не подтверждена владельцем стенда по документации своей поставки — не запускайте опыт. Данная предварительная настройка не заменяет включение встроенного storage менеджером.
Конфигуратор → Общие → Общие модули → УчебныеДвоичные85: Сервер/Вызов сервера=Да, Клиент/Привилегированный/Глобальный=Нет. Вставьте SERVER целиком. Storage manager только сервер; наличие глобального size-метода на клиенте не переносит native setters в client context.
Создайте свою внешнюю обработку с управляемой формой, строковыми реквизитами МеткаСвоейБазы36 и Подтверждение100 и командой ВыполнитьОпыт. Вставьте supporting CLIENT целиком. Никакого автостарта/HTTP/UI upload/file dialogs или фонового расписания нет.
Войдите под единственным своим администратором, закройте прочие свои сеансы, конфигуратор и фоновые задания. Native exclusive lock устанавливается только если возможно; чужие сеансы не завершаются и блокировки не снимаются принудительно. Общих реквизитов нет, поэтому области разделения не заданы.
Перед запуском каталог пуст, режим storage Запретить, состав0, external storage0. Введите свой marker и сначала неправильное подтверждение: данные не должны создаться. Затем сознательно введите СВОЙ ПУСТОЙ СТЕНД ДВОИЧНЫЕ85 и нажмите один раз. После ошибки/обрыва не повторяйте: собственные настройки/записи могли сохраниться частично.
Опыт создаст новый ownnonce и six real own catalog objects. Payload формируется только из nonce/номерафазы/256строк книги3×250=750 в памяти, UTF8 безBOM, bounded4..16KiB, ValueStorage безcompression. Ни чужие файлы, ни произвольный client payload/metadataID/SQL не принимаются.
Фазы1..4 последовательно устанавливают четыре native placement mode и проверяют getter, затем реально записывают новый own object и читают отдельно через real saved ref.GetObject/ValueStorage.Get. Проверяются own passport/тип/размер/SHA256. РежимCopyOnRead может копировать при чтении: такой read не обещан физически read-only; созданные свои storage copies не являются backup files.
Фаза5 устанавливает storage.ТолькоЧтение и все равно пишет еще один actual IBobject: native это разрешает и направляет новые binary values в БД. Фаза6 снова ReadAndWrite, но composition.DontUse только для own attribute, и еще одна real IBwrite/read. Состав берет actual metadata реквизита, не каталог целиком, не string и не runtime ValueStorage.
Все шесть сохраненных own objects затем повторно читаются/хешируются. Size API вызывается с пустым search-area array и include=[actual own catalog metadata], exclude=[]: не вся база и не все разделители. Результат — совокупные table+storage bytes, не суммаpayload/размерbackup/списокblob location; величина после не обязана равняться6×payload или строго возрастать.
На успешном завершении настройки сознательно остаются enabled/ReadAndWrite/default=false/threshold2048/composition.Use own attribute/CopyOnWrite, а свои шесть записей сохраняются. Не выключайте storage/не удаляйте его физические файлы: это не миграция оставшихся blobs обратно в БД. Exclusive0→1→0 принадлежит только этому сеансу; при ошибке снимается лишь собственная блокировка, если native снятие завершилось, без автоматического rollback policy/data.
Нельзя проверять failover остановкой production/локального storage process, менять внешние storage, делать backup/restore/ClearUnusedSpace или удалять файлы. Авторские проверки статические/native; реальная 1С/cluster/SQL/storage/UI/files/network не запускались и никаких backups не создано.
Функция ВыполнитьСвойОпытДвоичных85(МеткаСвоейБазы, Подтверждение) Экспорт
ПроверитьСвоюБазуДвоичных85(МеткаСвоейБазы);
Если Подтверждение <> "СВОЙ ПУСТОЙ СТЕНД ДВОИЧНЫЕ85" Тогда
ВызватьИсключение "Настройки собственного хранилища и данные не изменены";
КонецЕсли;
Если МонопольныйРежим() Или ПривилегированныйРежим() Тогда
ВызватьИсключение "Чужой монопольный/привилегированный контекст не принимается";
КонецЕсли;
Выборка = Справочники.УчебныеПакеты85.Выбрать();
Если Выборка.Следующий() Тогда
ВызватьИсключение "Свой новый каталог уже содержит данные; повтор запрещен";
КонецЕсли;
Если Не ХранилищеДвоичныхДанных.ПолучитьДоступностьХранилищаДвоичныхДанных() Тогда
ВызватьИсключение "Этот вариант платформы не поддерживает встроенное binary-store. Опыт не запускается";
КонецЕсли;
Если ХранилищеДвоичныхДанных.ПолучитьРежимИспользованияХранилищаДвоичныхДанных() <> РежимИспользованияХранилищаДвоичныхДанных.Запретить
Или ХранилищеДвоичныхДанных.ПолучитьСоставХранимыхДанных().Количество() <> 0
Или ВнешниеХранилищаДвоичныхДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен новый own стенд с выключенным встроенным storage, пустым составом и без внешних storage";
КонецЕсли;
КлючОпыта = Строка(Новый УникальныйИдентификатор);
Протокол = Новый Массив;
РазмерДо = ПолучитьРазмерТолькоСвоегоКаталога85();
Попытка
УстановитьМонопольныйРежим(Истина);
Если Не МонопольныйРежим() Тогда
ВызватьИсключение "Монопольный доступ собственного сеанса не подтвержден";
КонецЕсли;
ПроверитьСвоюБазуДвоичных85(МеткаСвоейБазы);
Выборка = Справочники.УчебныеПакеты85.Выбрать();
Если Выборка.Следующий() Или ВнешниеХранилищаДвоичныхДанных.Количество() <> 0
Или ХранилищеДвоичныхДанных.ПолучитьРежимИспользованияХранилищаДвоичныхДанных() <> РежимИспользованияХранилищаДвоичныхДанных.Запретить
Или ХранилищеДвоичныхДанных.ПолучитьСоставХранимыхДанных().Количество() <> 0 Тогда
ВызватьИсключение "После own exclusive получения начальное пустое состояние изменилось; ничего не перенастраиваем";
КонецЕсли;
ХранилищеДвоичныхДанных.УстановитьРежимИспользованияХранилищаДвоичныхДанных(РежимИспользованияХранилищаДвоичныхДанных.Разрешить);
Если ХранилищеДвоичныхДанных.ПолучитьРежимИспользованияХранилищаДвоичныхДанных() <> РежимИспользованияХранилищаДвоичныхДанных.Разрешить Тогда
ВызватьИсключение "Own enabled mode не подтвержден";
КонецЕсли;
ХранилищеДвоичныхДанных.УстановитьМинимальныйРазмерЗаписываемыхДанных(1024);
Если ХранилищеДвоичныхДанных.ПолучитьМинимальныйРазмерЗаписываемыхДанных() <> 2048 Тогда
ВызватьИсключение "Native clamp минимального порога1024→2048 не подтвердился";
КонецЕсли;
ХранилищеДвоичныхДанных.УстановитьМинимальныйРазмерЗаписываемыхДанных(2048);
ХранилищеДвоичныхДанных.УстановитьРежимЧтенияЗаписиХранилищаДвоичныхДанных(РежимЧтенияЗаписиХранилищаДвоичныхДанных.ЧтениеИЗапись);
Если ХранилищеДвоичныхДанных.ПолучитьРежимЧтенияЗаписиХранилищаДвоичныхДанных() <> РежимЧтенияЗаписиХранилищаДвоичныхДанных.ЧтениеИЗапись Тогда
ВызватьИсключение "Own storage read/write не подтвержден";
КонецЕсли;
ХранилищеДвоичныхДанных.УстановитьИспользованиеКакХранилищаПоУмолчанию(Истина);
Если Не ХранилищеДвоичныхДанных.ПолучитьИспользованиеКакХранилищаПоУмолчанию() Тогда
ВызватьИсключение "Own default=true не подтвержден";
КонецЕсли;
ХранилищеДвоичныхДанных.УстановитьИспользованиеКакХранилищаПоУмолчанию(Ложь);
Если ХранилищеДвоичныхДанных.ПолучитьИспользованиеКакХранилищаПоУмолчанию() Тогда
ВызватьИсключение "Own default=false не подтвержден";
КонецЕсли;
УстановитьТолькоСвойСостав85(ИспользованиеХраненияВХранилищеДвоичныхДанных.Использовать);
Режимы = Новый Массив;
Режимы.Добавить(РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных.РазмещениеКопийДанныхВХранилищеПриЗаписиВБазуДанных);
Режимы.Добавить(РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных.РазмещениеКопийДанныхВХранилищеПриЧтенииИзБазыДанных);
Режимы.Добавить(РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных.РазмещениеДанныхТолькоВХранилище);
Режимы.Добавить(РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных.РазмещениеДанныхВХранилищеИВБазеДанныхПриНедоступностиХранилища);
Для Номер = 0 По Режимы.Количество() - 1 Цикл
Режим = Режимы[Номер];
Если ТипЗнч(Режим) <> Тип("РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных") Тогда
ВызватьИсключение "Нужен настоящий native enum placement mode";
КонецЕсли;
ХранилищеДвоичныхДанных.УстановитьРежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных(Режим);
Если ХранилищеДвоичныхДанных.ПолучитьРежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных() <> Режим Тогда
ВызватьИсключение "Placement-mode own roundtrip не совпал. Проверьте ручную предварительную optimized-storage настройку своей базы";
КонецЕсли;
Протокол.Добавить(ЗаписатьИПрочитатьСвойПакет85(КлючОпыта, Номер + 1, Строка(Режим)));
КонецЦикла;
ХранилищеДвоичныхДанных.УстановитьРежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных(
РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных.РазмещениеКопийДанныхВХранилищеПриЗаписиВБазуДанных);
ХранилищеДвоичныхДанных.УстановитьРежимЧтенияЗаписиХранилищаДвоичныхДанных(РежимЧтенияЗаписиХранилищаДвоичныхДанных.ТолькоЧтение);
Если ХранилищеДвоичныхДанных.ПолучитьРежимЧтенияЗаписиХранилищаДвоичныхДанных() <> РежимЧтенияЗаписиХранилищаДвоичныхДанных.ТолькоЧтение Тогда
ВызватьИсключение "Storage read-only mode отдельно не подтвержден";
КонецЕсли;
Протокол.Добавить(ЗаписатьИПрочитатьСвойПакет85(КлючОпыта, 5, "StorageReadOnly: IB write permitted"));
ХранилищеДвоичныхДанных.УстановитьРежимЧтенияЗаписиХранилищаДвоичныхДанных(РежимЧтенияЗаписиХранилищаДвоичныхДанных.ЧтениеИЗапись);
УстановитьТолькоСвойСостав85(ИспользованиеХраненияВХранилищеДвоичныхДанных.НеИспользовать);
Протокол.Добавить(ЗаписатьИПрочитатьСвойПакет85(КлючОпыта, 6, "Own metadata attribute: DontUse"));
УстановитьТолькоСвойСостав85(ИспользованиеХраненияВХранилищеДвоичныхДанных.Использовать);
Если ХранилищеДвоичныхДанных.ПолучитьРежимИспользованияХранилищаДвоичныхДанных() <> РежимИспользованияХранилищаДвоичныхДанных.Разрешить
Или ХранилищеДвоичныхДанных.ПолучитьМинимальныйРазмерЗаписываемыхДанных() <> 2048
Или ХранилищеДвоичныхДанных.ПолучитьИспользованиеКакХранилищаПоУмолчанию()
Или ХранилищеДвоичныхДанных.ПолучитьРежимЧтенияЗаписиХранилищаДвоичныхДанных() <> РежимЧтенияЗаписиХранилищаДвоичныхДанных.ЧтениеИЗапись
Или ХранилищеДвоичныхДанных.ПолучитьРежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных()
<> РежимРазмещенияКопийДанныхВХранилищеДвоичныхДанных.РазмещениеКопийДанныхВХранилищеПриЗаписиВБазуДанных Тогда
ВызватьИсключение "Согласованная own final policy отдельно не подтверждена";
КонецЕсли;
ПроверитьВсеСвоиШестьПакетов85(КлючОпыта);
РазмерПосле = ПолучитьРазмерТолькоСвоегоКаталога85();
Если Протокол.Количество() <> 6 Или РазмерПосле < 0 Тогда
ВызватьИсключение "Own report ограничен шестью фазами и неотрицательным native size";
КонецЕсли;
Исключение
Если МонопольныйРежим() Тогда
УстановитьМонопольныйРежим(Ложь);
КонецЕсли;
ВызватьИсключение "Own опыт мог оставить настройки/данные частично. Монопольная блокировка снята, если native снятие завершилось; режимов/данных автоматически не откатываем, запуск не повторять";
КонецПопытки;
УстановитьМонопольныйРежим(Ложь);
Если МонопольныйРежим() Тогда
ВызватьИсключение "Own exclusive lock не снята; не объявляем завершение";
КонецЕсли;
Возврат Новый Структура("Ключ,Фазы,РазмерДо,РазмерПосле", КлючОпыта, Протокол, РазмерДо, РазмерПосле);
КонецФункции
Процедура УстановитьТолькоСвойСостав85(Хранение)
Если Не МонопольныйРежим() Или ВнешниеХранилищаДвоичныхДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен собственный exclusive-сеанс без других storage";
КонецЕсли;
Состав = Новый СоставХранимыхДанныхХранилищаДвоичныхДанных;
Состав.Добавить(Метаданные.Справочники.УчебныеПакеты85.Реквизиты.Данные, Хранение);
ХранилищеДвоичныхДанных.УстановитьСоставХранимыхДанных(Состав);
СвежийСостав = ХранилищеДвоичныхДанных.ПолучитьСоставХранимыхДанных();
Если СвежийСостав.Количество() <> 1 Тогда
ВызватьИсключение "Own состав должен содержать ровно один собственный attribute";
КонецЕсли;
Элемент = СвежийСостав.Получить(0);
Если Элемент.Метаданные <> Метаданные.Справочники.УчебныеПакеты85.Реквизиты.Данные Или Элемент.Хранение <> Хранение Тогда
ВызватьИсключение "Состав вернулся с чужим metadata или неправильным location flag";
КонецЕсли;
КонецПроцедуры
Функция ЗаписатьИПрочитатьСвойПакет85(КлючОпыта, Фаза, Режим)
Если Не МонопольныйРежим() Или Фаза < 1 Или Фаза > 6 Тогда
ВызватьИсключение "Own payload создается только в шести фазах одного своего exclusive опыта";
КонецЕсли;
Данные = ПолучитьСвойPayload85(КлючОпыта, Фаза);
Элемент = Справочники.УчебныеПакеты85.СоздатьЭлемент();
Элемент.Код = Строка(Новый УникальныйИдентификатор);
Элемент.Наименование = КлючОпыта + "|" + Строка(Фаза);
Элемент.КлючОпыта = КлючОпыта;
Элемент.Фаза = Фаза;
Элемент.Данные = Новый ХранилищеЗначения(Данные);
Элемент.Записать();
Свежий = Элемент.Ссылка.ПолучитьОбъект();
ПроверитьСвойПакет85(Свежий, КлючОпыта, Фаза);
Возврат Новый Структура("Фаза,Режим,БайтовPayload,ХешPayload,Ссылка", Фаза, Режим, Данные.Размер(),
Base64Строка(ХешироватьСвойPayload85(Данные)), Строка(Свежий.Ссылка));
КонецФункции
Функция ПолучитьСвойPayload85(КлючОпыта, Фаза)
UUIDКлюча = Новый УникальныйИдентификатор(КлючОпыта);
Если КлючОпыта <> Строка(UUIDКлюча) Или UUIDКлюча = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000")
Или Фаза < 1 Или Фаза > 6 Тогда
ВызватьИсключение "Нужен собственный canonical nonzero nonce и phase1..6";
КонецЕсли;
Текст = КлючОпыта + "|" + Строка(Фаза) + "|";
Для Номер = 1 По 256 Цикл
Текст = Текст + Строка(Номер) + ":Книга3×250=750;";
КонецЦикла;
Данные = ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь);
Если Данные.Размер() < 4096 Или Данные.Размер() > 16384 Тогда
ВызватьИсключение "Own bounded binary payload должен быть4..16KiB без чтения файлов";
КонецЕсли;
Возврат Данные;
КонецФункции
Функция ХешироватьСвойPayload85(Данные)
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(Данные);
Возврат Хеширование.ХешСумма;
КонецФункции
Процедура ПроверитьСвойПакет85(Свежий, КлючОпыта, Фаза)
Если Свежий = Неопределено Или Свежий.КлючОпыта <> КлючОпыта Или Свежий.Фаза <> Фаза
Или Свежий.Наименование <> КлючОпыта + "|" + Строка(Фаза) Или Свежий.ПометкаУдаления
Или ТипЗнч(Свежий.Данные) <> Тип("ХранилищеЗначения") Тогда
ВызватьИсключение "Actual own object passport не совпал";
КонецЕсли;
Прочитанные = Свежий.Данные.Получить();
Ожидаемые = ПолучитьСвойPayload85(КлючОпыта, Фаза);
Если ТипЗнч(Прочитанные) <> Тип("ДвоичныеДанные") Или Прочитанные.Размер() <> Ожидаемые.Размер()
Или Base64Строка(ХешироватьСвойPayload85(Прочитанные)) <> Base64Строка(ХешироватьСвойPayload85(Ожидаемые)) Тогда
ВызватьИсключение "Actual own fresh payload length/SHA256 не совпал";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьВсеСвоиШестьПакетов85(КлючОпыта)
Выборка = Справочники.УчебныеПакеты85.Выбрать();
Фазы = Новый Массив;
Пока Выборка.Следующий() Цикл
Если Фазы.Количество() >= 6 Или Выборка.КлючОпыта <> КлючОпыта Или Фазы.Найти(Выборка.Фаза) <> Неопределено Тогда
ВызватьИсключение "В своем sole catalog есть чужие/дублированные/лишние данные";
КонецЕсли;
ПроверитьСвойПакет85(Выборка.Ссылка.ПолучитьОбъект(), КлючОпыта, Выборка.Фаза);
Фазы.Добавить(Выборка.Фаза);
КонецЦикла;
Если Фазы.Количество() <> 6 Тогда
ВызватьИсключение "Own six phases после финальной настройки не подтвердились";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьРазмерТолькоСвоегоКаталога85()
Включить = Новый Массив;
Включить.Добавить(Метаданные.Справочники.УчебныеПакеты85);
Размер = ПолучитьРазмерДанныхБазыДанныхИХранилищаДвоичныхДанных(Новый Массив, Включить, Новый Массив);
Если ТипЗнч(Размер) <> Тип("Число") Или Размер < 0 Тогда
ВызватьИсключение "Native size собственных таблиц+storage должен быть неотрицательным числом байтов";
КонецЕсли;
Возврат Размер;
КонецФункции
Процедура ПроверитьСвоюБазуДвоичных85(МеткаСвоейБазы)
ПроверитьСвойПустойСтенд();
UUIDМетки = Новый УникальныйИдентификатор(МеткаСвоейБазы);
Если МеткаСвоейБазы <> Строка(UUIDМетки) Или UUIDМетки = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
ВызватьИсключение "Own ref marker должен быть каноническим ненулевым UUID, не realIBUUID";
КонецЕсли;
ОжидаемоеСоединение = "Srvr=""localhost:1541"";Ref=""Уч85Двоичные_" + МеткаСвоейБазы + """;";
Если СтрокаСоединенияИнформационнойБазы() <> ОжидаемоеСоединение Тогда
ВызватьИсключение "Допускается только exact own localhost:1541/ref connection, без file/prod/других параметров. Строка соединения не выводится";
КонецЕсли;
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
ВызватьИсключение "Нужен единственный real собственный IBUser";
КонецЕсли;
Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
Или Текущий.Имя <> "Уч85Двоичные_" + МеткаСвоейБазы Тогда
ВызватьИсключение "Real current own IBUser не подтвержден";
КонецЕсли;
Мета = Метаданные.Справочники.УчебныеПакеты85;
Если Мета.Имя <> "УчебныеПакеты85" Или Мета.Иерархический Или Мета.ТабличныеЧасти.Количество() <> 0
Или Мета.Реквизиты.Количество() <> 3 Или Метаданные.Боты.Количество() <> 0
Или Метаданные.Константы.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0
Или Мета.Реквизиты.Данные.Тип.Типы().Количество() <> 1
Или Мета.Реквизиты.КлючОпыта.Тип.Типы().Количество() <> 1 Или Мета.Реквизиты.Фаза.Тип.Типы().Количество() <> 1
Или Не Мета.Реквизиты.Данные.Тип.СодержитТип(Тип("ХранилищеЗначения"))
Или Не Мета.Реквизиты.КлючОпыта.Тип.СодержитТип(Тип("Строка"))
Или Не Мета.Реквизиты.Фаза.Тип.СодержитТип(Тип("Число")) Тогда
ВызватьИсключение "Нужна только own exact catalog schema с тремя реквизитами и без разделителей/служебных данных опыта";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыПолный модуль собственной управляемой формы: one-shot запуск и bounded отчет
Собственная внешняя обработка → Управляемая форма → Модуль формы.
Модуль управляемой формы, клиент только выводит own отчет; native storage setters и ValueStorage ctor остаются серверными.
Перем ОпытНачат85;
&НаКлиенте
Процедура ВыполнитьОпыт(Команда)
Если ОпытНачат85 = Истина Тогда
ВызватьИсключение "Повтор запрещен: storage policy/свои записи могли уже измениться";
КонецЕсли;
ОпытНачат85 = Истина;
Протокол = ВыполнитьНаСервере85();
Сообщить("Own nonce: " + Протокол.Ключ + "; шесть фаз проверены чтением/SHA256. Это не physical-placement proof");
Для Каждого Фаза Из Протокол.Фазы Цикл
Сообщить("Фаза " + Строка(Фаза.Фаза) + ": " + Фаза.Режим + "; own payload " + Строка(Фаза.БайтовPayload) + "байт; SHA256(base64)=" + Фаза.ХешPayload);
КонецЦикла;
Сообщить("Размер только своего каталога, native tables+storage bytes: до=" + Строка(Протокол.РазмерДо) + ", после=" + Строка(Протокол.РазмерПосле));
Сообщить("Это не размер отдельных физически размещенных blobs/backup и не тест отказоустойчивости. Own записи сохранены, storage оставлен включенным; exclusive lock снята");
КонецПроцедуры
&НаСервере
Функция ВыполнитьНаСервере85()
Возврат УчебныеДвоичные85.ВыполнитьСвойОпытДвоичных85(МеткаСвоейБазы, Подтверждение);
КонецФункцииРазбор по шагам
До изменений guard проверяет exactCF/version, one local client-server Ref/marker, one actualIBUser, three typed own catalog fields, отсутствие других данных/разделителей/расширений и externalstores0.
Административные действия отличаются от ValueStorage constructor: только native глобальный ХранилищеДвоичныхДанных manager изменяет настройки всей собственной базы. ValueStorage хранит значение и сам не выбирает физический сервер/путь.
Exclusive context первоначально0, затем native1 внутри Try и последовательно0 success/catch. Native невозможность установки не обходится termination чужих сеансов.
Enable создает storage при отсутствии, threshold1024 clamps2048 и это подтверждается getter; default true/false переключается только пока свой каталог пуст, затем own attribute composition explicitly controls записи.
Placement enum четырех фаз readonly/native, свойства не присваиваются. Каждый setter имеет настоящий аргумент нужного типа и отдельный getter; missing optimized prerequisite не подменяется invented setter.
Six own records имеют реальные сохраненные ссылки, own nonce/phase/name, binary data4..16KiB и свежие проверенныеSHA256. StandardCode новый UUID — собственный код, не fake reference identity.
Native ReadOnly не приводит к учебному ожиданию исключения при IBwrite: пятая запись успешно читается в собственномpreparedruntime. Это native-described behavior, не измеренная нами запись физическихDB страниц.
Composition содержит actual own Данные attribute и useflag. Возвращаемые Item.Metadata/Location readonly только сверяются. Objects already mapped другим storage native rejects; ownfixtureexternal0/emptycomposition это исключает в подготовке, не подменяет migration.
Scoped size uses3native arguments and onlyownmetadata include. Не заявляется равенствоphysicalbytes=payloadbytes, storegrowth, отказоустойчивость или runtime вашего сервера.
Как проверить результат
Actual own six saved refs после записи читаются отдельно; паспорта,4..16KiB размеры иSHA256 совпадают для всех фаз, включая ReadOnly/DontUse.
После native exclusive acquisition заново проверяется пустой own каталог/disabled storage/emptycomposition/external0 до первой мутации, чтобы предварительное чтение не стало ошибочной защитой от изменения состояния.
SetMinWrite1024 подтвердил native2048 clamp. Все четыре placement getter совпали с заданными native enum, финальный storage enabled/ReadAndWrite/defaultfalse/owncomposition.Use.
Фаза5 IBwrite не ожидает исключения: exact native ReadOnly page прямо разрешает сохранение новыхbinarydata вБД независимо от включенияstore.
Scope размера явно own catalog через include metadata, search=[]/exclude=[]; возвращены числабайтов, не полныетаблицы чужойбазы или обещанное равенствоpayloadbytes.
Exclusive lock принадлежит только своему сеансу и снимаетсяsuccess/catch, еслиnative release успешен; policy/данные не объявляются откатившимися при ошибке.
Ожидаемый результат
При самостоятельном успешном запуске полностью подготовленного собственного стенда отчет содержит6фаз, реальные ownpayload размеры/SHA256 и scoped native table+storage bytes до/после. Все6own records сохранены, финальная policy оставленаenabled, exclusive снята. Проверка содержимого не доказывает физическое размещение каждого байта/failover. Здесь runtime0, не живой результат вашей базы.
На что обратить внимание
У менеджера нет native constructor: он доступен через readonly глобальное свойство ХранилищеДвоичныхДанных, только на сервере. Не присваивайте глобальное свойство и не создавайте Новый МенеджерХранилищаДвоичныхДанных.
Client-server/local/address marker иmetadata guard — страховки, не доказательство ownership чужого server instance. Новый собственный выделенный кластер/IB по подготовке обязателен.
SupportAvailability говорит о поддержке варианта платформы, не successful storage connectivity/current mode/optimizedDB. Ее True не доказывает все prerequisites.
Native placement setter требует optimized DB binary storage, которое готовит владелец по точной своей документации. Здесь BSLsetter/CLIflag отсутствует честно; при неподтвержденной prerequisite опыт не готов к запуску.
MinSize1024 не является допустимым физическим порогом: native clamps к2048. Payload bound и ValueStorage безcompression позволяют не ошибиться на меньшемcompressed value, но точный serialized overhead не измерялся.
ReadOnly storage не делает IB/каталог readonly: writes идут в БД. Не превращайте режим в access-control или защиту документов от записи.
CopyOnWrite хранит данные в storage и служебной таблице; CopyOnRead пишет в служебную таблицу и синхронно копирует при первом read. DataPlacementToStorageOnly поnative чтению также имеет попыткуfallback из служебной таблицы при ошибке, но само имя не обещает существование полнойDBкопии.
DataPlacementToStorageAndDatabaseOnInaccessibleStorage при невозможностиstore-write пишетвDB; это не гарантия всех старыхblobs вDB и не проведенный failover test. Недоступность специально не создается.
Один metadata attribute нельзя одновременно включить в состав разныхstore. Не копируйте состав из чужой production или не переименовывайте существующий storage: здесь они отсутствуют заранее.
Policy setters/DB writes не обещаны одной общей транзакцией. Отмена собственного exclusive lock не откатывает policy, сохраненныеobjects или storagecopies; никаких автоматических реставраций/повторов.
Size API может быть дорогим, не учитывает историюданных ирасширения, учитывает только доступныечтению данные. Свой малыйcatalog нужен для ограниченного учебного scope; результат не является physical-location/backup proof.
Финальное enabled оставлено сознательно: отключениеstorage после StorageOnly не равно миграцииpayloadвDB. Delete files/cleanup/backups не входят в код и не выполнялись при подготовкеурока.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.