Коротко. Продукт рендерит схему ленты сам: 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.
-
Метрика запаса — что именно считает продукт:
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— предмет разбора. -
Сколько кассет в группах ленты — их отдаёт библиотека (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. Считать сумму кассет в классах данных/чётности — именно она сравнивается со схемой. -
Что видит реестр продукта (на узле, от
marvin):bash T=/opt/ampli/apps/foos/bin/tapecmd; CONF=$(ls /opt/ampli/cfg/foos/*.conf | head -1) $T --config $CONF media listОжидаются кассеты с группами и поколениями. Пустой список при живых кассетах в библиотеке — другая проблема (реестр, не запас). -
Свободная кассета под 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. -
Схема ленты, которую продукт реально применяет:
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 — массиве независимых библиотек). Продукт не спрашивает оператора, сколько кассет «хватит»: он рендерит схему из модели и считает запас по ней.
Механика в двух шагах:
- Схема задаёт, на сколько кассет раскладывается полоса записи (
spreadwidth) и сколько кассет разрешено потерять (safety). В нашем рендере это2и1. - Минимум кассет в группах =
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 у части кассет.
Решение (штатное)
-
Довести число кассет в группах до трёх (две в данных/чётности + одна страховочная по схеме
2 + 1). Кассета заводится в библиотеку с валидным штрихкодом, группу назначает продукт. Ожидаемо после цикла: три кассеты в классах данных/чётности. -
Держать минимум одну свободную кассету вне групп — она попадает в
genscratch, без неё архив не стартует даже при формально достаточном запасе. -
Перечитать состояние штатными задачами. Ждать ближайший цикл
tape_safety_check(до часа) либо дать продукту пройти задачи после изменения модели ленты. Ручной прогон периодики допустим штатными телами задач, расписание при этом не меняется. -
Закрыть событие после того, как метрика показала ненулевой запас:
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.