壊れたWhatsAppのデータベース(msgstore.db)を復元する

WhatsAppはチャット履歴のすべてを、msgstore.dbというたった1つのSQLiteファイルに保存しています。ページやポインタが1つ壊れただけで、SQLiteはメッセージの大半がまだ中に残っていてもファイル全体を malformed(不正)として拒否します — そしてそれを取り戻すために、あなたの会話のデータベースを見知らぬ他人のサーバーへ渡す必要などあってはなりません。

ファイルがデバイスから出ることはありません — 修復はブラウザ内で実行されます。アップロードは 0 バイトです。

Your data is the big block — usually intact. What breaks is the small index. Repair rebuilds it.

Drop a file here or browseTap to choose a file

ZIP · Office · PDF · video · JPG · PNG · RAR/7z · SQLite — repaired right here in your browser. Nothing is uploaded

0 bytes uploadedFree: 3 repairs/day — up to 500 MB video, 100 MB docs & archives, 50 MB photos. Free download. Single repair €5.90. No account required.

今すぐ修復

  1. ファイルをドロップ
  2. 修復はローカルで実行
  3. 結果をダウンロード

WhatsApp(Android版)はすべての会話をmsgstore.dbという単一のSQLiteデータベースに保存します — メッセージの本文、タイムスタンプ、チャットや連絡先への参照が、すべてこの中にあります。アプリの突然終了、端末からファイルを取り出す途中で中断されたコピー、あるいは中途半端に終わった同期がこれを壊すと、WhatsAppも他のあらゆるSQLiteツールも、ファイル全体を "database disk image is malformed"(ディスク上のデータベースイメージが不正です)として拒否します。すでに復号済みのmsgstore.dbを上にドロップすれば、ツールがそのページをローカルに走査し、スキーマを組み直し、まだデコードできる行をすべて、新しく開けるデータベースへ再挿入します — あなたのメッセージ履歴すべてを保持するチャットのデータベースが、アップロードされることは一切ありません。

msgstore.dbの中身 — ページ、テーブル、そして -wal サイドカー

WhatsAppのデータベースはごく普通のSQLiteファイルなので、固定サイズのページが並んだフラットな配列です(SQLiteの既定値はたいてい4 KB)。先頭16バイトはマジック文字列SQLite format 3\0で、ページ 1の残りにはファイルヘッダーと、すべてのテーブルを列挙するsqlite_schemaが入っています。各テーブルはb-tree(Bツリー)です。内部ページは葉ページへ下っていくポインタを持ち、葉ページに実際の行が格納されています。

チャット履歴にとって重要なテーブルは決まっています。最近のWhatsAppはメッセージをmessageテーブル(古いバージョンではmessages)に、会話リストをchatに、電話番号やグループの識別子をjidに保存します。メッセージの本文はテキスト列(新しいスキーマではtext_data、古いスキーマではdata)にあり、各行にはUnixエポックのミリ秒単位のタイムスタンプが付いています。message_mediamessage_thumbnailmessage_quotedcall_logといった補助テーブルが残りを補います。そして肝心なのは、写真・動画・ボイスメモそのものはデータベースの中には入っていないという点です — それらはWhatsAppのMediaフォルダにある別々のファイルで、データベースはそのファイルパスと小さなサムネイルだけを保持しています。

WhatsAppはこのデータベースをWAL(ライトアヘッドログ)モードで動かしているので、端末上ではその隣に2つの兄弟ファイルが見えます。msgstore.db-walmsgstore.db-shmです。最近コミットされたメッセージは、メインの.dbへチェックポイントされるまで-walファイルの中だけに存在していることがあります。このサイドカーがあるなら、必ず取っておいてください — そのコミット済みフレームこそが、いちばん新しい行だからです。

なぜ "malformed" と出るのか — そして .crypt の罠

SQLiteは、ポインタをたどった先が有効なb-treeページでないもの — ゼロで埋まったページ、不正なセルオフセット、ファイルサイズと食い違うページ数 — に行き着いた瞬間に、SQLITE_CORRUPT(結果コード11)を投げます。これが"database disk image is malformed"(ディスク上のデータベースイメージが不正です)として表に出るのです。SQLiteは最初の不整合で止まります。だからこそ、内部ページが1つ壊れただけでファイル全体が倒れる一方で、その先にある無傷の葉ページにはあなたのメッセージがまだ残っているのです。近い仲間のエラー"file is not a database,"(ファイルがデータベースではありません)は、16バイトのヘッダーのマジックそのものが壊された、という意味で、その後ろのページは無事なことが多いです。

この破損はたいてい、書き込みの中断から生まれます。WhatsAppがまだファイルを開いたままの状態で、USB経由やファイルマネージャでmsgstore.dbを端末から取り出すと、チェックポイントが途中の、ちぎれたファイルをコピーしてしまうことがあります。故障しかけたSDカードや同期での1ビットの反転、あるいは書き込みの途中で電源を失った端末も、同じことを引き起こします。切り詰められた(truncated)コピーは、単純に末尾にあったページを丸ごと失います。

ほとんどの人が最初にはまる罠があります。WhatsAppのバックアップフォルダにあるファイルは、普通のデータベースではありません。バックアップはmsgstore.db.crypt14msgstore.db.crypt15という名前で、AES-GCMで暗号化されています(鍵は/data/data/com.whatsapp/files/keyにあり、crypt15の場合はあなたのエンドツーエンドのバックアップ用パスワードの背後にあります)。.crypt14/.crypt15ファイルは高エントロピーのノイズとして読み取られ — SQLiteのヘッダーがまったく無いので、普通のmsgstore.dbへ復号し直すまで、ページ復旧が手を付けることはできません。このツールは、暗号化されたバックアップではなく、すでに復号済みのデータベースを対象に動きます。

復旧で何が戻るのか — そしてチャットのDBを絶対にアップロードしない理由

壊れたポインタを信用する代わりに、ツールはファイルをページごとに読み取ります。スキーマを組み直し、各テーブルのb-treeを歩き、ポインタの連鎖ではもう届かないものについては、葉ページから自己記述型のレコードを直接デコードする、生ページの総なめ(raw page sweep)に切り替えます。見つけた行の周りにb-treeをゼロから組み直し、あなたがダウンロードする真新しいデータベースへ書き出します — SQLite自身の.recoverコマンドと同じ戦略です。既知のテーブルに割り当てられない行は、捨てずにlost_and_foundテーブルへ入れます。そしてmsgstore.db-walサイドカーを渡せば、そのコミット済みフレームが先に重ね合わされるので、結果は最後のチェックポイントではなく、あなたの最後にコミットされたメッセージを反映します。

正直な限界も述べます。物理的に上書きされた、あるいはファイル末尾から切り詰められたバイトは失われており、どんなツールもそれを作り出すことはできません。値はディスク上のストレージクラスのまま戻ってくるので、列のアフィニティ(型親和性)がずれることがあります。総なめはフリーリスト(freelist)や未圧縮(unvacuumed)のページも読むため、以前に削除されたメッセージが再び現れることもあります。復旧されたデータは常に疑わしいものです — SQLite自身のドキュメントがそう述べています — ので、頼りにする前に、信頼できる情報源と照らし合わせて検証してください。そしてメディアの本体は依然として別のMediaフォルダにあります。データベースが返してくれるのはテキストと参照であって、画像そのものではありません。

なぜこれをブラウザ内でやるのか?チャットのデータベースは、自分の管理下にないサーバーへ渡すには最悪のファイルです — あなたが今までにやり取りした、あらゆるメッセージ・電話番号・タイムスタンプを丸ごと含みうるからです。アップロード方式の「修復」ツールは、そのファイルを、あなたには中身を確かめられないインフラへ、あなたが書いたわけでもない保持期間の条件のもとでコピーします。ここではファイルはあなたのディスクから読み込まれ、あなたのタブの中で組み直されます。Networkパネル(ネットワーク)を開けば、データベースのバイトが1バイトもあなたの端末から出ていないことを確認できます。

修復できるものとできないもの

修復できる

  • "Database disk image is malformed"(SQLITE_CORRUPT 11)— 壊れたページ、または壊れたb-treeポインタによるもの
  • "File is not a database" — 16バイトのヘッダーのマジックだけが壊され、その後ろのページが無事な場合
  • WhatsAppが開いたままの状態で端末からコピーしたために、ちぎれた、あるいはチェックポイントが途中のmsgstore.db
  • 切り詰められたデータベース — 生き残ったページのメッセージ行をすべて取り出し、さらに渡された -wal サイドカーから未チェックポイント(未反映)の行も取り出します
  • ポインタの連鎖がもう届かないページにある行 — 生ページの総なめでlost_and_foundへ復旧します

修復できない

  • 鍵のない暗号化バックアップ .crypt14 / .crypt15 — SQLiteヘッダーを持たない暗号文なので、まず復号する必要があります
  • 物理的に上書きされた、あるいはファイル末尾で切り詰められたメッセージ — そのバイトはもう存在しません
  • 写真・動画・ボイスメモそのもの(Mediaフォルダにある別々のファイルであり、データベースの中にはありません)
  • 復旧された各メッセージが完全である、あるいは正しいという保証 — 復旧データは信頼できる情報源と照合して検証してください
  • 0バイトのファイル、またはヘッダーもページもすべてノイズのデータベース(それはまず、ストレージ復旧の問題です)

修復が失敗した場合、その理由(データの欠落か構造の破損か)をお伝えします。失敗した修復に料金が請求されることはありません。

よくある質問

WhatsAppが "database disk image is malformed" と出ます。チャットはもう消えたのでしょうか?

たいていは違います。これはSQLiteのSQLITE_CORRUPT(コード11)です。エンジンが不整合なページやポインタに1つ突き当たってファイル全体を拒否した、という意味であって、あなたのメッセージが消去されたわけではありません。messageの行は、ほぼ必ずまだ葉ページの中に残っています。ファイルをページごとに歩き、きちんとデコードできる行の周りに新しいデータベースを組み直せば、たいていは履歴が戻ってきます。

.crypt14 / .crypt15 のバックアップしかありません。それを復元できますか?

直接はできません。.crypt14.crypt15ファイルはAES-GCMで暗号化されていてSQLiteヘッダーを持たないので、WhatsAppの鍵(crypt15の場合は64桁のエンドツーエンドのバックアップ鍵)を使って普通のmsgstore.dbへ復号し直すまでは、純粋なノイズとして読み取られます。復号済みのmsgstore.dbを手に入れたら、ここにドロップすれば、その上で復旧が実行されます。

写真や動画も一緒に戻ってきますか?

データベースが保持しているのは、メッセージの本文、タイムスタンプ、そしてファイルへの参照であって、メディアの本体ではありません。写真・動画・ボイスメモは、WhatsAppのMediaフォルダに別々のファイルとして保存され、データベースの中に残るのは小さなサムネイルだけです。msgstore.dbを復旧すると会話とメディアへのポインタが戻りますが、メディアファイルそのものは、そのフォルダから別途復旧します。

データベースの隣に msgstore.db-wal というファイルがあります。これは重要ですか?

はい、しばしば大いに重要です。WhatsAppはWALモードで動くので、あなたの最も新しいコミット済みメッセージは、チェックポイントされるまでmsgstore.db-walサイドカーの中だけに存在していることがあります。これは取っておいて、メインの.dbと一緒に追加してください。そのコミット済みフレームは走査の前に重ね合わされるので、復旧されたデータベースは最後のチェックポイントではなく、あなたの最後にコミットされたトランザクションを反映します。

修復のために、私のチャットのデータベースはアップロードされますか?

いいえ。ファイルはあなたのディスクから読み込まれ、ブラウザのタブの中で組み直されます。何も送信されません。チャットのデータベースは、他人のサーバーに置きたくない筆頭のファイルです — あなたがやり取りしたあらゆるメッセージと番号を含みうるからです — ので、Networkパネル(ネットワーク)を開いて、データベースのバイトが1バイトもあなたの端末から出ていないことを確認できます。

関連: あらゆるSQLiteデータベースを修復する · 壊れたWhatsAppの動画を修復する · アップロードゼロを検証する