ActiveScaleинженерная практика

Кассеты «пропали», safety = 0: форма штрихкода и реестр кассет

Обслуживание tapecassettebarcodesafetycold-storage

Коротко. Продукт сверяет кассеты по штрихкоду, но при чтении из библиотеки отбрасывает последние два знака (LTO-суффикс). Если кассета заведена в реестр полной 8-значной формой 000281L8, она никогда не совпадёт с библиотекой и навсегда останется «отсутствующей» — отсюда AUTODECOMMISSION_BACKOFF и нулевой tape safety. В реестре нужна форма без суффикса: 000281. Штрихкод брать только с железа, а не из каталога эмулятора или из памяти.


1. Как продукт сверяет кассеты

Цепочка простая и в ней одно неочевидное звено:

  1. Библиотека отдаёт каталог кассет со штрихкодами (запрос вида /sws/v2/media/fsmedlist/state?format=JSON).
  2. Продукт читает штрихкод и режет его: в коде это помечено как «Drop LTO identifier» — barcode = barcode[:-2].
  3. Полученный набор сравнивается с реестром кассет продукта (transportd).

Значит, у библиотеки и у продукта разные формы одного и того же штрихкода. На наклейке кассеты и в каталоге библиотеки — 8 знаков с суффиксом (000281L8). В реестре продукта — 6 знаков без суффикса (000281). Любая запись «полной» формой обречена: сокращённый библиотечный штрихкод с ней не совпадёт никогда.

Это не «глюк сверки»: механизм задуман так, чтобы один и тот же штрихкод работал для LTO разных поколений. Ошибка возникает на стороне того, кто заводит кассеты в реестр.


2. Две формы — где какая

Где Форма Пример
наклейка на кассете, каталог библиотеки 8 знаков с LTO-суффиксом 000281L8
реестр продукта (transportd) 6 знаков без суффикса 000281
события и метрики как в реестре 000281

Правило для оператора: считывать с железа, записывать без суффикса. Не «переводить» штрихкод из головы и не брать из каталога эмулятора: каталог может не отражать фактический состав библиотеки (в нашей практике он однажды совпал по количеству, но разошёлся по составу — в нём были кассеты, которых в железе нет, и не было той, что стояла в приводе).


3. Симптомы неверной формы

  • COLD_STORAGE_TAPE_DECOMMISSIONED (INFO) с пустым barcode — продукт снял запись с учёта.
  • COLD_STORAGE_TAPE_AUTODECOMMISSION_BACKOFF (ERROR) с полями missing_tapes и max_tape_allowed — «пропавших» больше предохранительного порога, снос отложен.
  • COLD_STORAGE_TAPE_SAFETY_EQUALS_ZERO (WARNING) — в ленточном тире нет резервной копии.
  • В missing_tape_media — записи с датой missing_since, обычно сразу после перерегистрации кассет.

Ключевая деталь: библиотека при этом отдаёт все кассеты как available, а метрика transportd_tape_library_media{status="OK"} показывает полное число. То есть расхождение не в ленте, а в сверке — искать надо форму записи, а не железо.

Предохранитель спасает не всегда: если «пропавших» не больше порога, продукт действительно снимает кассеты с учёта. В нашей конфигурации порог был 2 — при 5 «пропавших» снос откладывался, но события продолжали идти каждые ~4 часа.


4. Реестр: как заводить правильно

Штатный путь — завести кассету со штрихкодом (инструмент вида connector_add_medium.py <штрихкод> --uuid <uuid> --apply), где <штрихкод> уже в продуктовой форме.

Что важно знать про уже испорченные записи:

  • Изменить запись нельзя. Повторное добавление на существующий uuid даёт FailedSequenceException.
  • Удаление не срабатывает. media remove отчитывается «removed successfully», но запись остаётся.
  • wipe-generation не находит такие записи — он работает только с кассетами, у которых назначена группа и поколение. У записей, заведённых по uuid, группа пуста, поколение -1, поэтому «снёс 0».

Рабочий порядок: дать продукту «усыновить» кассеты (он сам пишет их в группу ленты), после чего провести retire → register уже в правильной форме. Пока это не сделано, записи стоит привести в нейтральный статус и помнить, что safety останется нулевым.

Для точечных операций используйте адресные вызовы по одному uuid: tapecmd media set-status --status Marked --persist, затем статусы marked/compacted и tapecmd media wipe-generation … --persist.


5. Safety: почему нуль и сколько кассет нужно

Safety — не «сколько кассет в библиотеке», а сколько резервных копий допускает схема ленты. Схема задаёт два числа: ширину раскладки (spread) и запас (safety). Требуемое число кассет в группах — их сумма.

Пример из практики: spreadwidth = 2 и safety = 1 требуют 3 кассеты в группах ленты. Если их две, достижимый запас — 0, и продукт поднимает SAFETY_EQUALS_ZERO. Лечится либо доведением групп до нужного числа кассет, либо согласованным снижением ожидания в модели — но не «правкой метрики».

Смотреть надо метрики, а не только события: minimum_tape_safety, across_tape_safety, across_tape_spreadwidth, decommissioned_media.


6. Чего не делать

  • Не убирать из библиотеки кассету, заведённую в продукте. Через заданное окно (у нас — 96 часов) продукт снимет её сам, и вы получите «пропавшую» кассету с реальными последствиями.
  • Не гонять media unused --delete --persist оптом. Операция не различает «мусор» и живые записи; удалять только адресно.
  • Не править рендер конфигурации руками. Следующая реконфигурация вернёт прежнее состояние, а расхождение останется.
  • Не заводить кассеты по uuid без штрихкода. Именно так появляются «призраки»: запись есть, сопоставить её с библиотекой невозможно, и она навсегда «отсутствует».
  • Не доверять каталогу эмулятора как источнику штрихкодов. Только физическая библиотека.

7. Проверка

Наш полевой инструмент обслуживания реестра печатает расхождение прямо:

!! WRONG BARCODE FORM (with LTO suffix) - the product strips it and sees these as missing

Он же показывает три среза: каталог библиотеки, реестр продукта, missing_tape_media, и метрики порта метрик. Запуск — в режиме проверки (запись по умолчанию dry-run, реальные изменения — только с --apply).

Ожидаемое состояние: число кассет в каталоге равно числу записей в реестре; ни одна запись не помечена «неверной формой»; minimum_tape_safety больше нуля; missing_tape_media пуст.


8. Профилактика

  • Один стандарт формы на всю площадку: наклейка — 8 знаков, реестр — 6. Записать это в регламент.
  • Заводить кассеты сразу со штрихкодом, а не по uuid.
  • После каждой замены кассеты — сверять каталог библиотеки и реестр, а не ждать события.
  • С 7.1 продукт умеет поднимать COLD_STORAGE_INVALID_BARCODE_DETECTED — это штатный сигнал о невалидном штрихкоде, его не надо игнорировать.
  • Держать число кассет в группах не ниже суммы spread+safety: иначе safety 0 становится штатным состоянием, а к нему привыкают.

Источники

  • Cold Storage Tech Brief — RAIL, 2D erasure coding, overhead (2026-11-07)
  • ActiveScale Software Release Notes — цифровые штрихкоды, COLD_STORAGE_INVALID_BARCODE_DETECTED, де-коммишн кассет в 7.3 (2026-11-07)
  • Наша практика (обезличено): разбор «пропавших» кассет, формы штрихкода и safety на стенде с ленточной библиотекой.
  • Обновлено: 2026-11-07.

Нужен инженер? Разберу вашу ситуацию и скажу, что делать — по шагам, с проверками.

Обсудить задачу