Раскладка bbolt metadata (актуально по коду)

Файл фиксирует фактическую схему в iobackup/internal/storage/bboltstore/store.go. Bucket schema хранит JSON storage_schema_record (version): при открытии БД версия должна быть <= SupportedStorageSchemaVersion агента; иначе старт завершается ошибкой до миграций.

Bucket’ы

Bucket Значение value Первичный ключ
jobs JSON job.Job metadata.job_id (primary «by id»; отдельного bucket jobs_by_id нет)
jobs_by_uid индекс: value = job_id ключ job_uid
jobs_by_previous_id индекс: value = job_id ключ previous_job_id
job_revisions_by_id JSON storage.JobRevision job_revision_id
job_revisions_by_job индекс: value = job_revision_id ключ "{job_uid}/{zero_padded_revision}"
runs JSON storage.Run run_id
runs_by_job индекс: value = run_id ключ "{job_id}:{run_id}"
idempotency_by_job индекс: value = run_id ключ "{job_uid}/{idempotency_key}" (replay POST run)
idempotency_key_owner индекс: value = job_uid ключ idempotency_key (конфликт при другом job_uid)
task_runs JSON storage.TaskRun task_run_id
task_runs_by_run индекс: value = task_run_id ключ "{run_id}:{task_run_id}"
artifacts JSON storage.BackupManifest backup_id
manifests JSON storage.BackupManifest backup_id
manifests_by_job индекс: backup_id "{job_id}:{backup_id}"
manifests_by_task индекс "{task_id}:{backup_id}"
manifests_by_created_at индекс ключ "{YYYYMMDDHHMMSS}:{backup_id}", value backup_id
notification_events JSON storage.NotificationEvent notification_event_id
notification_events_by_run индекс ключ "{run_id}:{notification_event_id}"
notification_events_by_task индекс ключ "{task_id}:{notification_event_id}"
retention_cleanup_events JSON storage.RetentionCleanupEvent event_id
retention_cleanup_events_by_job индекс "{job_id}:{event_id}"
retention_cleanup_events_by_task индекс "{task_id}:{event_id}"
verification_results JSON storage.VerificationResult verification_id
verification_results_by_backup индекс "{backup_id}:{verification_id}"
verification_results_by_job индекс "{job_id}:{verification_id}"
job_verification_runs JSON storage.JobVerificationRun verify_run_id
job_verification_runs_by_job индекс "{job_id}:{verify_run_id}"
task_log_lines JSON storage.TaskLogLine см. код AppendTaskLogLine
schedules JSON scheduler.Schedule (v2+) schedule_id
schedules_by_job индекс: value = ключ schedules ключ "{job_uid}/{schedule_id}"
schedule_states JSON scheduler.ScheduleState (v2+) schedule_id (см. internal/storage/bboltstore/schedule_store.go)
schedule_events JSON scheduler.ScheduleEvent (v3+) см. schedule_diag_store.go (per-schedule + глобальный time index)
schedule_decisions JSON scheduler.ScheduleDecision (v3+) см. schedule_diag_store.go
offline_spool_items JSON offlinespool.Item (v4+) spool_id
offline_spool_by_status индекс: value = spool_id ключ s\x00{status}\x00{pad_unix_ns}\x00{spool_id}
offline_spool_by_kind индекс k\x00{kind}\x00{pad}\x00{spool_id}
offline_spool_by_entity индекс + idempotency map e\x00{entity_type}\x00{entity_id}\x00{pad}\x00{spool_id} и i\x00{idempotency_key}spool_id
offline_spool_by_created_at индекс c\x00{pad}\x00{spool_id}
offline_spool_dead_letter индекс для dead_letter (v4+) d\x00{pad}\x00{spool_id}
offline_spool_state JSON offlinespool.SpoolState ключ singleton
schema JSON storage_schema_record { "version": … } ключ "storage_schema_record" (см. SupportedStorageSchemaVersion)
locks JSON storage.Lock lock_key

RetentionCleanupEvent.status (в т.ч. dry_run, deleted, ошибки удаления) описан в docs/features/retention/retention-semantics.md и docs/features/retention/retention-behavior.md.

JSON storage.BackupManifest (0.17-fix.40): помимо legacy полей artifact/checksum/source_type, документ может содержать manifest_id, lineage, repository, artifacts[] (роли data/manifest/…), checksums[] (scopes artifact/plaintext/…), source/destination блоки, artifact_format, compression, checks, restore, immutability, catalog — см. internal/storage/models.go и manifest_types.go.

Ключи: job_id vs job_uid

Некоторые исторические индексы продолжают использовать job_id в ключе (например runs_by_job, manifests_by_job) ради backward compatibility. Where applicable, higher-level логика должна сначала резолвить job_id → job_uid (через jobs_by_uid и job record), а затем опираться на job_uid-семантику (например для idempotency и revisions).

Idempotency индексы

Функции индексов appendIndex / putIndex см. начало store.go.

Связь JobRecord → JobRevision (0.17-fix.20)

В jobs хранится JobRecord в виде JSON job.Job (в т.ч. metadata.*). Для модели revisions используются поля:

JobRevision хранится отдельно в job_revisions_by_id и индексируется в job_revisions_by_job ключом вида:

job_01J.../00000000000000000003 -> jrev_01J...

Backward compatibility

Старые записи (до 0.17-fix.20) могут не содержать полей revisions/snapshots в Run/TaskRun/JobRecord. Благодаря omitempty и JSON unmarshal по именам полей:

Metadata health / check (0.17-fix.60)

Поведение при обслуживании

Версионирование и миграции (0.31.x + v0.42.x)