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

S3 507 Storage is full при свободных дисках

Диагностика s3507dsspolicybarometercapacity

Коротко. 507 Insufficient Storage на PUT — не про занятое место, а про решение раскладки: политика DSS не помещается в доступное число блоксторов (w + s > N) или упирается в лимит «блоксторов с локации». Сначала читайте барометр DSS, число живых блоксторов и параметры политики, а не df. Штатное лечение — политика, которая влезает.


Симптом

  • PUT любого объекта, включая пробный файл в несколько мегабайт, возвращает 507 Insufficient Storage, реже в журнале DSS — 129: storage is full.
  • df -h на blockstore-маунтах показывает свободные терабайты; сырая ёмкость далека от исчерпания.
  • Витрина durability в GUI пустая или неполная; колонка бывает CONFIGURED, но ёмкость под раскладку не размечена.
  • Листинг и HEAD работают, чтение старых объектов проходит — ломается именно запись.
  • В журнале DSS-клиента повторяется: incomplete spread: [...] (width 9), policy spread width: 13 → DSS_Exc.StorageFull → 129: storage is full.

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

Проверки DSS — через консоль продукта: sudo -i; sherpa -c "<одна строка>". Порт DSS указывать явно — port=11060 (значение по умолчанию 23510 даёт connection refused).

  1. Барометр и ёмкость: python cli.dss.capacity.read_barometer() # ожидается 'ok' cli.dss.capacity.read_capacity() # raw / free / usable full при свободных дисках — подтверждение, что дело в раскладке, а не в месте.

  2. Живые блоксторы (не записи в списке): python live = [v for v in cli.dss.blockstore.list_all(port=11060).values() if v.get('status') == 'ok'] print len(live) Ожидается число из плана раскладки. Записи abandoned живыми не считаются.

  3. Неймспейсы: python cli.dss.capacity.get_namespaces_with_fill_status() Ожидается status: ok у каждого.

  4. Политика: python cli.dss.policy.list_all() cli.dss.policy.show(<POLICY_ID>) Ожидается spread_width (w), safety (s), hierarchy_rules. Дальше считать w + s ≤ N.

  5. Размечена ли ёмкость колонки в модели: bash sudo curl -sk --cert /opt/ampli/cfg/marvin/ssl/machine.cert \ --key /opt/ampli/cfg/marvin/ssl/machine.key \ https://127.0.0.1:8443/model/column/ Ожидается CONFIGURED и непустой resources. resources: null — отдельный дефект.

  6. Чем недоволен генератор: bash sudo tail -50 /opt/ampli/var/log/dssclientdaemon/*/clientx.log Ожидается: строк incomplete spread и StorageFull нет. В скобках видно, сколько блоксторов собрано и сколько требует политика.


Причина

507 — admission-решение, а не остаток места

Полоса состоит из w фрагментов данных и s чётности. Чтобы записать объект, генератору нужно разложить w + s фрагментов по разным блоксторам. Нет подходящих блоксторов — раскладка не собирается, DSS отвечает StorageFull, шлюз отдаёт 507. Байты при этом на месте: их некуда положить по правилам политики.

Отсюда: usable = (w − s) / w, условие работоспособности — w + s ≤ N, где N — число блоксторов.

Ловушка: считать блоксторы с локаций, а не диски

Политика может влезать по общему числу блоксторов и не влезать по лимиту локации. Правило data_balance_rule: [100,100,3] означает «не больше 3 блоксторов с локации»; при трёх локациях генератор видит максимум 3 × 3 = 9 блоксторов при нужных 13 — запись встаёт, хотя дисков десятки. Считать надо (блоксторов на локацию) × (число локаций), а не «всего дисков».

Рабочий пример из практики: политика 14/4 с правилом [100,100,60] («до 60 с локации») набирает 14 из 24. Рабочей её делает лимит 60, а не сами числа 14/4.

Третий случай: ёмкость колонки не размечена

Колонка CONFIGURED, но resources: null: витрина пуста, задачи column.update_all_buckets и dss.blockstore_status_consistency падают, запись может отдавать 507. Это следствие незавершённого прогона установщика — ёмкость приходит по цепочке enclosure → diskgroup → allocation, которую заполняет полный прогон на реальном железе.

Что здесь гипотеза

Механизм доказан строками incomplete spread и кодом 129. Если барометр ok, w + s ≤ N выполняется, а 507 остаётся — гипотеза о неполном наборе живых блоксторов либо о неразмеченной ёмкости колонки; проверяется п.2 и п.5.


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

  1. Посчитать до правок: N живых блоксторов, требуемое w + s, лимит локации. Если w + s > N — политика не подходит, и это надо признать до изменений.

  2. Выбрать политику, которая влезает. Для малого числа блоксторов штатный слот — своя политика с category: custom; имя вида balanced-8 схема не принимает (жёсткий список) и отвечает 500 ValidationError. Ориентиры — в формуле политики DSS.

  3. Создать политику и выбрать её (GUI или Model API): bash sudo curl -sk --cert /opt/ampli/cfg/marvin/ssl/machine.cert \ --key /opt/ampli/cfg/marvin/ssl/machine.key \ -X PUT -H "Content-Type: application/json" \ -d '{"selectedstoragepolicy": {"category": "custom", "small_file_threshold": 524288}}' \ "https://127.0.0.1:8443/model/environment/<ENV_GUID>/" Ожидается 200; продукт сам пересчитает колонки. Без заголовка Content-Type PUT даёт 400.

  4. Либо через DSS-консоль: python cli.dss.policy.add(<W>, <S>, [100,100,60], port=11060) for name in cli.dss.namespace.list_all(): cli.dss.namespace.change_policy(name, '<POLICY_ID>', port=11060) Грабли: change_policy ждёт имя неймспейса и строковые аргументы; числовой id даёт bucket is not valid: Name shorter than 3. Успех — None.

  5. Колонка без resources: догнать полный прогон установщика до штатного финала, а не «доливать» ёмкость. column_bucket_update до финала держать выключенной — она падает, пока ёмкость не размечена.

  6. Проверить запись пробным объектом, и только потом пускать приложение.

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

  • Смена политики — не форматирование: меняется схема вновь записываемых экстентов, существующие объекты остаются читаемыми. Критичные данные перестраховать, работу делать в окно обслуживания и по отмашке.
  • Ручная инъекция ёмкости — не штатно, временная мера: маскирует дефект и искажает витрину. План замены — полный прогон установщика.
  • Удаление данных ради места — не решение: при w + s > N освобождение байтов ничего не меняет.

Проверка

  • Барометр → ok; у всех неймспейсов status: ok.
  • w + s ≤ N, запас больше нуля.
  • PUT пробного объекта → 200; GET/HEAD → 200, тело совпадает.
  • В clientx.log новых incomplete spread / 129: storage is full нет.
  • В модели selectedstoragepolicy не null; у колонки непустой resources (для третьего случая).

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

  • Считать политику до установки: в config-ng.ini (policy_type) закладывать ветку под реальное число блоксторов.
  • Не оставлять запас 0: политика, занимающая ровно N, встанет при первом отказе диска.
  • Пересчитывать N после расширения.
  • Не смешивать raw и usable: usable меньше на долю чётности.
  • Проверять лимит локации, а не только общее число блоксторов.
  • Гейт приёмки: барометр ok, неймспейсы ok, пробный PUT 200, витрина политики не пустая.

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

  • Вендор: ActiveScale Datasheet DS00546A (дата доступа 2026-11-07)
  • Вендор: Software Documentation Center 7.3 (дата доступа 2026-11-07)
  • Наша практика (обезличено): политики под реальное число блоксторов; кейсы 507 при свободных дисках на стендах из трёх нод.
  • Обновлено: 2026-11-07.

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

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