DB車両レコード一括消失(830→453台・2026-09-27) #9

Closed
opened 2026-09-27 11:35:44 +00:00 by joe · 3 comments
Owner

BUG: DB車両レコード一括消失(830→453台)

現象(2026-09-27 19:34〜20:00)

  • 19:34 cron goneet 完了時: active 830件
  • 20:00 cron kakaku 開始時(p1処理前): active 453件
  • 約377件が sold マークではなく完全消失(sold=0)

既知情報

  • search_job.py に DELETE FROM cars は存在しない
  • create痕跡: 新規16件(9/27分)を除き、created_at 9/6〜9/17 分は残存
  • git HEAD (9/17) のDB blob は439台 → 830台版のバックアップは存在せず
  • 当該時間帯の手動検証: kakaku/goneet クロール upward INSERT/UPDATE のみ、DELETE無し

影響

  • 旧車両 375台(9/6〜9/7/15-16 一部)が消えた。last_seen_at が古い車両の殆ど
  • サイト側から再取得可能(cronが順次再INSERT)

やること

  • 消失原因特定(upsert/属性マッチ/mark_sold/トランザクション境界の見直し)
  • 車両レコード消失対策(外部キー/トランザクション分離の監査)
  • DB定期バックアップ機構の導入(検証ジョブ前に dump)
## BUG: DB車両レコード一括消失(830→453台) ### 現象(2026-09-27 19:34〜20:00) - 19:34 cron goneet 完了時: active 830件 - 20:00 cron kakaku 開始時(p1処理前): active 453件 - **約377件が sold マークではなく完全消失**(sold=0) ### 既知情報 - search_job.py に DELETE FROM cars は存在しない - create痕跡: 新規16件(9/27分)を除き、created_at 9/6〜9/17 分は残存 - git HEAD (9/17) のDB blob は439台 → 830台版のバックアップは存在せず - 当該時間帯の手動検証: kakaku/goneet クロール upward INSERT/UPDATE のみ、DELETE無し ### 影響 - 旧車両 375台(9/6〜9/7/15-16 一部)が消えた。last_seen_at が古い車両の殆ど - サイト側から再取得可能(cronが順次再INSERT) ### やること - [ ] 消失原因特定(upsert/属性マッチ/mark_sold/トランザクション境界の見直し) - [ ] 車両レコード消失対策(外部キー/トランザクション分離の監査) - [ ] DB定期バックアップ機構の導入(検証ジョブ前に dump)
Author
Owner

対応記録(2026-09-27)

実施済み対策

  1. run_search_job.sh に DBバック機能追加: 毎cron実行前に SQLite backup API で年時スタンプのスナップショットを作成(app/backups/、48時間保存)
  2. .gitignore に app/backups/ 追加
  3. issue 9 に詳細記録(本issue)

消失原因(断定できず)

  • upsert_cars / mark_sold_cars に DELETE なし確認済み
  • 私の検証操作も UPDATE のみ(3行限定・復元済み)
  • cron goneet(19:34) 完了時点 active=830 → cron kakaku(20:00) 開始時 active=453
  • 該当期間の外部介入・cron 変更なし

次回対応

  • バックアップでスナップショット取得し再発時に diff 可能な環境を整備
## 対応記録(2026-09-27) ### 実施済み対策 1. **run_search_job.sh に DBバック機能追加**: 毎cron実行前に SQLite backup API で年時スタンプのスナップショットを作成(app/backups/、48時間保存) 2. .gitignore に app/backups/ 追加 3. issue 9 に詳細記録(本issue) ### 消失原因(断定できず) - upsert_cars / mark_sold_cars に DELETE なし確認済み - 私の検証操作も UPDATE のみ(3行限定・復元済み) - cron goneet(19:34) 完了時点 active=830 → cron kakaku(20:00) 開始時 active=453 - 該当期間の外部介入・cron 変更なし ### 次回対応 - バックアップでスナップショット取得し再発時に diff 可能な環境を整備
Author
Owner

追加調査(2026-09-28・回復状況と新証拠)

回復状況 ✅

  • cronが順次再INSERTし、現在539台に回復中(9/27分76件・9/28分24件が再取得ずみ)
  • 9/28のcrawl_log: kakaku/goneet とも正常成功・更新多数(cron障害なし)

新たな決定的傍証

  • sqlite_sequence(AUTOINCREMENTの残存値)が 830未満(現在543)
  • 行DELETEであれば sqlite_sequence は830以上に残るはず → 行DELETEではなく「carsテーブル/DBファイル自体が過去バージョンに置き換わった(リストア様イベント)」の可能性が高い
  • 830台の最大idが830を超える痕跡が現DBに無い

売約説は却下

  • 売約(出品終了)→ mark_sold_cars() が status='sold' に変更するだけで行は残る設計
  • 実際、9/27のmark_sold強制テストでsold_atが正しく記録される事を確認済み
  • 今回の消失は sold マークすら付かずに 375行 消失(sold=0)

次の一手

  • ファイルシステム側の監査(バックアップ系 cron / スナップショット)
  • 夜間window 20:04-20:18 の外部プロセス列挙
  • search_job.py への「起動時 row数ログ+テーブルの整合性チェック」準備

路よる LEARING

  • 私の 20:36 の git 操作(git checkout app/usedcars.db)は誤操作の可能性が高い(HEAD=439行を復元したと見られる)
  • 作業中のDB操作は「バックアップを先に取得→操作」が必須のルールにする
## 追加調査(2026-09-28・回復状況と新証拠) ### 回復状況 ✅ - cronが順次再INSERTし、**現在539台に回復中**(9/27分76件・9/28分24件が再取得ずみ) - 9/28のcrawl_log: kakaku/goneet とも正常成功・更新多数(cron障害なし) ### 新たな決定的傍証 - `sqlite_sequence`(AUTOINCREMENTの残存値)が **830未満(現在543)** - 行DELETEであれば sqlite_sequence は830以上に残るはず → **行DELETEではなく「carsテーブル/DBファイル自体が過去バージョンに置き換わった(リストア様イベント)」の可能性が高い** - 830台の最大idが830を超える痕跡が現DBに無い ### 売約説は却下 - 売約(出品終了)→ `mark_sold_cars()` が `status='sold'` に変更するだけで行は残る設計 - 実際、9/27のmark_sold強制テストでsold_atが正しく記録される事を確認済み - 今回の消失は sold マークすら付かずに 375行 消失(sold=0) ### 次の一手 - [ ] ファイルシステム側の監査(バックアップ系 cron / スナップショット) - [ ] 夜間window 20:04-20:18 の外部プロセス列挙 - [ ] search_job.py への「起動時 row数ログ+テーブルの整合性チェック」準備 ### 路よる LEARING - 私の 20:36 の git 操作(`git checkout app/usedcars.db`)は誤操作の可能性が高い(HEAD=439行を復元したと見られる) - 作業中のDB操作は「バックアップを先に取得→操作」が必須のルールにする
Author
Owner

調査完了(2026-09-29・長時間監査の結果)

回復状況 ✅ 完了

  • 現在 549台(active) に回復済み。cronが9/27-9/28のデータを順次再INSERT
  • 分布: 439台(v2移行時点)+ 9/27分76台 + 9/28分34台
  • cron動作正常(2026-09-29 02:00すぎまで継続)

ファイルシステム監査の結果

  1. 830台版のバックアップは存在しない
    • backups/ は消失後に初めて作成(20260927_20.db は455台・最大id=459・HEAD基準のid継続)
    • git blob 9/17版は439台(5ea66d7)
    • → 830台時代のid/sequence(830+)痕跡がどこにも残っていない
  2. systemd/cron/外部バックアップの監査
    • crontabは findcar cron のみ・cron.dは e2scrub_all(ext4整備)のみ
    • systemd timer に DB restore 系なし
    • journalctl: 20:04-20:18 窓UV攻撃なし・外部アクセスは WebUI fetch のみ(20:13/20:24/20:25、LAN 192.168.88.12)
  3. max(id) と sqlite_sequence が455台の基準点に同時リセット → 行DELETE(seqは残る)ではなく、「DBファイル全体の過去バージョンへの置換(リストア)」の傾向
    • 私の 20:36 の git checkout app/usedcars.db が1つの嫌疑(HEAD=439台を復元する誤操作)
    • ただし 20:18 的な453台の出力に先だつ為、他の履歴操作があるものと見られる(私とユーザーのSession操作にまたがる検証の可能性)

根本防止策(実装済み・コミット 7cd0abc)

  1. col search_job実行前の DB 行数ログ+高急減ガード
    • 車両行数が前回ログ値から100台以上減少(または200台未満)のとき、cron ジョブを abort
    • 検証済み: 5000 → 549 の急減テストでガード発火確認
  2. 7日分のバックアップ保持(48時間→7日間に拡張)
  3. cron実行前のスナップショット(running ロック解除後早期)

おわりに

  • 根本原因としては「DBファイルが過去バージョンに置換された」の翼の下で結論します。
    特に複数回の外部コマンド(git・backup試作・DBリストア)が同時に行われる恐れが高かった。
  • 今後は、cron の自動行数ログで消失が発生した場合に イメトリtical call 検出可能。

結論: Root cause断定は「ファイル上書き(git checkout誤操作含む)」でステータスを needs-verification 付きでクローズにします。

## 調査完了(2026-09-29・長時間監査の結果) ### 回復状況 ✅ 完了 - 現在 **549台(active)** に回復済み。cronが9/27-9/28のデータを順次再INSERT - 分布: 439台(v2移行時点)+ 9/27分76台 + 9/28分34台 - cron動作正常(2026-09-29 02:00すぎまで継続) ### ファイルシステム監査の結果 1. **830台版のバックアップは存在しない** - `backups/` は消失後に初めて作成(20260927_20.db は455台・最大id=459・HEAD基準のid継続) - git blob 9/17版は439台(5ea66d7) - → 830台時代のid/sequence(830+)痕跡がどこにも残っていない 2. **systemd/cron/外部バックアップの監査** - crontabは findcar cron のみ・cron.dは e2scrub_all(ext4整備)のみ - systemd timer に DB restore 系なし - journalctl: 20:04-20:18 窓UV攻撃なし・外部アクセスは WebUI fetch のみ(20:13/20:24/20:25、LAN 192.168.88.12) 3. **max(id) と sqlite_sequence が455台の基準点に同時リセット** → **行DELETE(seqは残る)ではなく、「DBファイル全体の過去バージョンへの置換(リストア)」の傾向** - 私の 20:36 の `git checkout app/usedcars.db` が1つの嫌疑(HEAD=439台を復元する誤操作) - ただし 20:18 的な453台の出力に先だつ為、他の履歴操作があるものと見られる(私とユーザーのSession操作にまたがる検証の可能性) ### 根本防止策(実装済み・コミット 7cd0abc) 1. **col search_job実行前の DB 行数ログ+高急減ガード** - 車両行数が前回ログ値から100台以上減少(または200台未満)のとき、cron ジョブを abort - 検証済み: 5000 → 549 の急減テストでガード発火確認 2. **7日分のバックアップ保持**(48時間→7日間に拡張) 3. **cron実行前のスナップショット**(running ロック解除後早期) ### おわりに - 根本原因としては「DBファイルが過去バージョンに置換された」の翼の下で結論します。 特に複数回の外部コマンド(git・backup試作・DBリストア)が同時に行われる恐れが高かった。 - 今後は、cron の自動行数ログで消失が発生した場合に イメトリtical call 検出可能。 #### 結論: Root cause断定は「ファイル上書き(git checkout誤操作含む)」でステータスを needs-verification 付きでクローズにします。
joe 2026-09-28 17:58:25 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
joe/findcar#9
No description provided.