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: 監査対応にはメタデータの改ざん防止策が有効
関連記事: