01
全体像 — 問題は4段階で進んだ
混入、潜伏、顕在化、復旧を一本の時間軸で見る。
結論:TerraformやECRがイメージを書き換えたのではない。ローカルのbuild contextとGitの内容が一致していなかった。
| 段階 | 起きたこと | 見えていた状態 |
|---|---|---|
| 混入 | 未追跡migrationを含めて f303e43 をbuild | tagは正常に見える |
| 潜伏 | RDSへ 20260603225644 を適用 | 旧イメージでは動く |
| 顕在化 | 33a1292 に必要なmigrationがない | revision 7が失敗 |
| 復旧 | migrationを戻して 1ddc111 をbuild | revision 8が成功 |
02
根本原因 — Gitの外側までDockerは運ぶ
commit hashのtagは、イメージ内容の清潔さを保証しない。
. にあるものをbuild contextとして扱う。GIT_COMMIT_HASH := $(git rev-parse --short HEAD)
docker build --platform=linux/arm64 \
-t db-migrator-stg:${GIT_COMMIT_HASH} \
-f Dockerfile .
# Dockerfile
COPY . .
COPY --from=builder /app/db ./db
実測では、f303e43 のGit treeにない正しいmigrationとtypo側migrationが、同じtagのDockerイメージ内には存在した。
| 場所 | 正しいmigration | typo migration |
|---|---|---|
| Git commit f303e43 | なし | なし |
| Docker image f303e43 | あり | あり |
| 現在のRDS | version適用済み | DBは存在しない |
03
なぜ今回なのか — 一致していた旧ペアを崩した
問題は新しく作られたのではなく、新しいイメージへの切り替えで発見された。
旧ペア:偶然整合
RDSは 20260603225644 を記録。旧イメージ f303e43 は、Git外から混入した対応ファイルを持っていた。
→
新ペア:不整合が露出
RDSの履歴は同じまま。新イメージ 33a1292 には対応するup/downがなく、revision 7で停止した。
failed to apply migrations: no migration found for version 20260603225644: read down ... file does not exist
これはrollbackを要求するエラーではない。DBの現在versionに対応するmigration pairを、実行中のイメージから見つけられないという整合性エラー。
04
復旧 — typoだけでなく正しい履歴も戻す
1回目は混入除去だけ。2回目でDBとGitの履歴を再び一致させた。
- commit 22b3bf3 からup / down / dump.sqlを復旧
- 3ファイルだけをcommitし、新tag 1ddc111 を作成
- ARM64・no-cacheでbuildし、
slack_metricsだけを収録していることを確認 - ECRへpushし、task definition revision 8へ登録
dbName=slack_metrics、finish to apply migrations、Run task completed!を確認
schema_migrations を削除・強制変更して合わせる方法は採用しなかった。DBだけを書き換えると、履歴の不整合を広げるため。05
現在地と残作業
障害復旧は完了。再発防止と講座単位のGit整理が残る。
| 確認項目 | 現在の状態 |
|---|---|
| ECS task definition | revision 8 / ARM64 |
| 使用イメージ | db-migrator-stg:1ddc111 |
| ECR digest | sha256:e4cc1b20…c9863137 |
| migration実行 | 成功 |
slack_netrics DB | 現在存在しない |
| Parameter Store image tag | 未作成 |
残り
- db-migratorのecspresso変更を章単位でcommitする
aws.mkのbuild platformをARM64へ戻す- 未追跡migrationがあればbuildを止めるguardを追加する
- batch側ファイル名を教材どおり
ecs-task-def.overrides.jsonへ揃える - 作業を続けない場合は、現在availableのRDSを停止する
古いimage f303e43、失敗image 33a1292、revision 7は残っているが、最新revision 8は参照していない。削除は緊急ではない。
今回の要点
- Gitのcommit hashをtagにしても、未追跡ファイルを含むbuild contextまでは保証できない。
- migrationはDBとイメージの両側で履歴が連続して初めて安全に動く。
- 今回は元migrationを復旧する正攻法で、revision 8まで正常化した。