2026年10月29日

2026年10月29日

バックアップのメタデータを記録・管理する方法

はじめに

バックアップファイルそのものだけでなく、「いつ・何を・どこから・どの方式で・どれだけのサイズで・成功か失敗か」というメタデータを残しておくことは、リストア時の意思決定や監査対応で極めて重要です。

本記事ではJSON Lines形式のメタデータログ、SQLiteによる集中管理、SHA-256チェックサムによる完全性検証までを実装例で解説します。

症状・背景

  • バックアップファイルが多数あり、どれが最新で完全か把握できない
  • 監査でバックアップ実行履歴の提出を求められたが追跡できない
  • 復元時にどのバックアップに何が含まれるか不明
  • ファイルが転送中に壊れていてもそれに気づかない

手順・設定方法

ステップ1: メタデータの設計と必須項目

# 1バックアップ = 1 JSONレコード
cat <<'EOF'
{
  "id": "srv01-mysql-20260514T0200",
  "host": "srv01.example.com",
  "type": "mysql-logical",
  "started_at": "2026-05-14T02:00:00+09:00",
  "finished_at": "2026-05-14T02:08:31+09:00",
  "size_bytes": 251658240,
  "sha256": "9f3c...",
  "destination": "s3://backup/srv01/full-20260514.sql.gz",
  "retention_days": 30,
  "status": "success"
}
EOF

ステップ2: シェルスクリプトでメタデータを記録

#!/bin/bash
# /usr/local/sbin/backup-with-meta.sh
set -euo pipefail
META=/var/log/backup/meta.jsonl
SRC=/var/backups/mysql/full-$(date +%F).sql.gz
START=$(date -Iseconds)
mysqldump --defaults-extra-file=/etc/mysql/backup.cnf --single-transaction \
  --all-databases | gzip -9 > "$SRC"
END=$(date -Iseconds)
HASH=$(sha256sum "$SRC" | awk '{print $1}')
SIZE=$(stat -c%s "$SRC")
# jqで安全にJSONを組み立てる
jq -nc --arg id "srv01-$(basename "$SRC")" --arg s "$START" --arg e "$END" \
   --arg h "$HASH" --argjson z "$SIZE" --arg p "$SRC" \
   '{id:$id,host:"srv01",type:"mysql-logical",started_at:$s,finished_at:$e,
     sha256:$h,size_bytes:$z,path:$p,status:"success"}' >> "$META"

ステップ3: SQLiteで集中管理

# DB作成
sqlite3 /var/lib/backup-meta/index.db <<'SQL'
CREATE TABLE IF NOT EXISTS backups (
  id TEXT PRIMARY KEY,
  host TEXT, type TEXT,
  started_at TEXT, finished_at TEXT,
  size_bytes INTEGER, sha256 TEXT,
  path TEXT, status TEXT,
  retention_days INTEGER DEFAULT 30
);
CREATE INDEX idx_host_time ON backups(host, started_at DESC);
SQL
# JSONLからインポート
jq -r '[.id,.host,.type,.started_at,.finished_at,.size_bytes,.sha256,.path,.status]|@tsv' \
  /var/log/backup/meta.jsonl \
  | sqlite3 -separator $'\t' /var/lib/backup-meta/index.db \
    ".import /dev/stdin backups"

ステップ4: 検索と完全性検証

# 過去7日の成功バックアップを一覧
sqlite3 /var/lib/backup-meta/index.db \
  "SELECT host, type, finished_at, size_bytes/1024/1024 AS mb
   FROM backups WHERE status='success'
   AND started_at > datetime('now','-7 days') ORDER BY started_at DESC;"
# SHA-256で完全性検証
EXPECTED=$(sqlite3 /var/lib/backup-meta/index.db \
  "SELECT sha256 FROM backups WHERE id='srv01-full-20260514.sql.gz';")
ACTUAL=$(sha256sum /var/backups/mysql/full-20260514.sql.gz | awk '{print $1}')
[ "$EXPECTED" = "$ACTUAL" ] && echo "OK: 完全性OK" || echo "NG: 破損の可能性"

注意事項

  • メタデータDB自体もバックアップ対象に含める。これを失うと履歴が消える
  • SHA-256計算は大容量だと時間がかかる。アップロード前にローカルで計算し転送先と比較するのが効率的
  • パス・ホスト名などにスペースや特殊文字が入ると壊れやすいので必ずjqで組み立てJSONエンコードする
  • 監査要件がある場合はメタデータの改ざん防止として書き込み専用ログ(append-onlyやS3 Object Lock)を併用

まとめ

1. 構造化メタデータ: JSON Linesは追記しやすく機械処理に最適

2. チェックサム: SHA-256で転送・保管中の破損を検知

3. SQLite集中管理: 検索・集計が容易で運用負荷が小さい

4. 必須5項目: 対象・時刻・サイズ・ハッシュ・保存先は最低限記録

5. append-only: 監査対応にはメタデータの改ざん防止策が有効

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲