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

COLD_STORAGE_TAPE_SAFETY_EQUALS_ZERO

Диагностика tapesafetycold-storagecassettelibrarytroubleshoot

Коротко. Продукт рендерит схему ленты сам: spreadwidth = 2 плюс safety = 1 требуют трёх кассет в группах ленты. Если в группах две кассеты, достижимый запас равен нулю, и раз в час поднимается COLD_STORAGE_TAPE_SAFETY_EQUALS_ZERO (WARNING). Архив при этом обычно идёт — это не отказ, а сигнал «запас на отказ кассеты нулевой». Лечится добавлением кассет, а не сбросом события.


Симптом

  • Событие COLD_STORAGE_TAPE_SAFETY_EQUALS_ZERO (severity WARNING) обновляется раз в час и не закрывается само.
  • В метрике tape_durability видно minimum_tape_safety = 0, при этом across_tape_spreadwidth = 2 и across_tape_safety = 1.
  • Плитка кластера зелёная, S3 отвечает, архивация объектов может проходить — поэтому событие часто игнорируют.
  • Рядом стоят счётчики decommissioned_media и across_tape_safety: если кассет мало и часть снята с учёта, разбор путается.

Симптом легко перепутать с «пропавшими» кассетами: картина похожая, лечение другое — см. «Пропавшие» кассеты.


Что проверить первым (read-only)

Все проверки — только чтение. Модель доступна по mTLS, сертификаты продукта root-only, поэтому запросы к модели — на узле, root.

  1. Метрика запаса — что именно считает продукт: bash curl -s http://127.0.0.1:9090/metric/tape_durability Ожидаются поля minimum_tape_safety, across_tape_safety, across_tape_spreadwidth, decommissioned_media. Ноль в minimum_tape_safety при spreadwidth = 2 — предмет разбора.

  2. Сколько кассет в группах ленты — их отдаёт библиотека (SWS), её продукт опрашивает каждые ~15 с: bash curl -sk "https://<CONNECTOR_HOST>/sws/v2/media/fsmedlist/state?format=JSON" \ | jq '.classes[] | {classId, available: (.available.medias|length)}' Ожидаются классы данных и чётности (вида as_…_d_0, as_…_p_0) и отдельный genscratch. Считать сумму кассет в классах данных/чётности — именно она сравнивается со схемой.

  3. Что видит реестр продукта (на узле, от marvin): bash T=/opt/ampli/apps/foos/bin/tapecmd; CONF=$(ls /opt/ampli/cfg/foos/*.conf | head -1) $T --config $CONF media list Ожидаются кассеты с группами и поколениями. Пустой список при живых кассетах в библиотеке — другая проблема (реестр, не запас).

  4. Свободная кассета под scratch — без неё архив не начнётся: bash curl -sk "https://<CONNECTOR_HOST>/sws/v2/media/fsmedlist/state?format=JSON" \ | jq '[.classes[] | select(.classId=="genscratch") | .available.medias|length] | add' Ожидается ≥ 1. Ноль даёт COLD_STORAGE_INSUFFICIENT_FREE_TAPE_MEDIA.

  5. Схема ленты, которую продукт реально применяет: bash sudo grep -E 'transport-(across|within)-(tape-)?(spreadwidth|safety)' /opt/ampli/cfg/foos/*.conf Ожидается transport-across-tape-spreadwidth=2 и transport-across-tape-safety=1. Значения меняются через модель/ConfigRule, руками в конфиге — нет.


Причина

Схема холодного тира — erasure coding на кассетах (по данным Quantum, холодный тир построен на 2D erasure coding и RAIL — массиве независимых библиотек). Продукт не спрашивает оператора, сколько кассет «хватит»: он рендерит схему из модели и считает запас по ней.

Механика в двух шагах:

  1. Схема задаёт, на сколько кассет раскладывается полоса записи (spreadwidth) и сколько кассет разрешено потерять (safety). В нашем рендере это 2 и 1.
  2. Минимум кассет в группах = spreadwidth + safety = 3. Достижимый запас = фактическое число кассет минус spreadwidth: при двух кассетах 2 − 2 = 0.

Отсюда WARNING: продукт не «сломан», он сообщает, что при потере одной кассеты данных не останется. Событие поднимает расписание coldstorage.tape_safety_check раз в час — ровно часовой такт и есть признак этой причины, а не случайного сбоя.

transport-manual-configuration=False означает, что значения рендерятся автоматически. Поэтому «подкрутить» их в конфиге на узле бессмысленно: ближайший configure вернёт вендорские значения.

Гипотеза: кассеты есть, но не в тех группах

Проверка: сумма кассет в классах ≥ 3, а minimum_tape_safety всё равно 0. Тогда кассеты стоят в genscratch и не разложены по классам данных/чётности — продукт назначает группу той записи, чей uuid библиотека называет в месте записи. Доказательство: tapecmd media list показывает пустую группу или поколение -1 у части кассет.


Решение (штатное)

  1. Довести число кассет в группах до трёх (две в данных/чётности + одна страховочная по схеме 2 + 1). Кассета заводится в библиотеку с валидным штрихкодом, группу назначает продукт. Ожидаемо после цикла: три кассеты в классах данных/чётности.

  2. Держать минимум одну свободную кассету вне групп — она попадает в genscratch, без неё архив не стартует даже при формально достаточном запасе.

  3. Перечитать состояние штатными задачами. Ждать ближайший цикл tape_safety_check (до часа) либо дать продукту пройти задачи после изменения модели ленты. Ручной прогон периодики допустим штатными телами задач, расписание при этом не меняется.

  4. Закрыть событие после того, как метрика показала ненулевой запас: HANDLED_AUTO либо ignore в GUI. Не закрывать «на будущее» до проверки метрики — следующий цикл поднимет событие снова.

Если штатный путь недоступен

Не штатно, временная мера. Если кассет физически нет, а архив нужен, единственный путь — снизить ожидание схемы (уменьшить spreadwidth/safety в модели ленты) либо уменьшить объём/схему томов так, чтобы уложиться в две кассеты. Это не увеличение запаса: при spreadwidth=2 и двух кассетах запас остаётся нулевым независимо от формулировок в отчёте.

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


Проверка

  • curl -s http://127.0.0.1:9090/metric/tape_durability → minimum_tape_safety ≥ 1, across_tape_spreadwidth = 2, across_tape_safety = 1.
  • GET /sws/v2/media/fsmedlist/state → три кассеты в классах данных/чётности, ≥ 1 в genscratch.
  • Новых COLD_STORAGE_TAPE_SAFETY_EQUALS_ZERO нет за два–три часовых цикла.
  • Задачи tape_safety_check, tape_media_verify, tape_drive_verify — SUCCESS.
  • Событие в GUI в HANDLED_AUTO/ARCHIVED, а не в LIVE.

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

  • Считать кассеты по формуле, а не «на глаз»: spreadwidth + safety — минимум для групп, плюс одна свободная под genscratch. Планирование — холодный тир и лента.
  • Не путать «кассета есть» и «кассета в группе». Реестр и библиотека — разные вещи; расхождение разбирается отдельно, по форме штрихкода.
  • Держать одну страховочную кассету сверх схемы — это условие ненулевого запаса при потере кассеты.
  • Мониторинг: minimum_tape_safety рядом с занятостью классов; TAPE_SAFETY_EQUALS_ZERO смотреть вместе с decommissioned_media, а не по отдельности.
  • После каждого изменения ленты — один цикл задач и проверка метрики, а не только закрытие события в GUI. Как читать события — События и задачи.

Источники и дата

  • Quantum, Cold Storage technical brief (TB00064A): https://cdn.allbound.com/iq-ab/2021/10/cold-storage-TB00064A.pdf (дата доступа: 2026-11-07) — 2D erasure coding, RAIL, overhead от 15%.
  • Quantum, Software Documentation Center (ActiveScale 7.3): https://qsupport.quantum.com/kb/flare/Content/ActiveScale/Software/Content/Index_Files/Index_Software.htm (дата доступа: 2026-11-07).
  • Наша практика, обезличено: разбор safety = 0 на стенде с двумя кассетами в группах; схема рендерится автоматически, значения 2 + 1.
  • Обновлено: 2026-11-07.

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

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