0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ヒヤリハット報告 #1 — メンバー名一括置換でDBが壊れた夜

0
Posted at

SQLiteの文字列一括置換でDBが壊れた話——保護トークン設計の落とし穴

個人開発サービス CheckMe の開発中に発生したインシデント記録です。同じ轍を踏まないよう公開します。

何が起きたか

深夜、SQLiteのレコード50件以上に対して「旧メンバー名→新名称」の一括置換スクリプトを実行した。二重置換を防ぐための「保護トークン方式」で実装したつもりが、トークン文字列に検索パターンの部分文字列が含まれていた。

バグの原因:トークンに検索対象が含まれていた

# NG: 'UIUXD' の中に 'UIUX' が含まれている
text = text.replace('UIUXトップディレクター', 'UIUXD')  # 保護
text = text.replace('UIUX', 'UIUXトップディレクター')           # ここでトークン内の UIUX にもヒット!
text = text.replace('UIUXD', 'UIUXトップディレクター') # 復元できない

結果として本番DBが以下の状態に:

'テックリードエンジニアエンジニア'     # 二重置換
'トップトップマーケッターッター'       # 三重置換
'UIUXトップディレクターD'     # 未復元の残骸

正しい実装:ASCII制御文字を使う

# OK:  + 短い識別子 +  — 日本語にも英数字にも含まれない
TOKENS = {
    'UIUXトップディレクター': 'A',
    'テックリードエンジニア':  'B',
    'トップマーケッター':      'C',
}

def apply(text, old_rules):
    for final, tok in TOKENS.items():
        text = text.replace(final, tok)   # Step1: 新名称を保護
    for old, tok in old_rules:
        text = text.replace(old, tok)     # Step2: 旧名称を置換
    for final, tok in TOKENS.items():
        text = text.replace(tok, final)   # Step3: 復元
    return text

第二の落とし穴:バックアップから戻したら今日の作業が消えた

バックアップは毎日03:00取得。22時に事故が発生し、バックアップから復元すると今日中に作成した記事・議事録・公開設定が全て消えた。

偶然残っていた .broken ファイルから救出したが、INSERT の UNIQUE constraint エラーでトランザクションが全ロールバックされ、3回目でようやく完全復元できた。

教訓:バックアップから戻す前に「いつのバックアップか」を必ず確認すること。

再発防止:deploy.sh にホットバックアップを追加

DB_BACKUP_FILE="${BACKUP_DIR}/rhyme_cache-$(date +%Y%m%d%H%M).db"
sqlite3 "$DB_SRC" ".backup '${DB_BACKUP_FILE}'"
ls -t "${BACKUP_DIR}"/rhyme_cache-*.db | tail -n +8 | xargs rm -f  # 7世代保持

sqlite3 .backup はコンテナ稼働中・書き込み中でも一貫性のあるスナップショットを取れる。

まとめ

  • 保護トークンは「検索パターンの部分文字列を含まない文字列」を使う(X 形式が確実)
  • バックアップ世代と取得時刻を必ず把握しておく
  • INSERT の UNIQUE 制約違反はトランザクション全体をロールバックする。INSERT OR REPLACEcommit の分割を使う

#Python #SQLite #個人開発 #インシデント #バグ修正

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?