Tailscale、16年前のSQLite WALリセットバグによるデータベース破損を追跡

Tailscale Traces Database Corruption to 16y/o SQLite WAL-Reset Bug

Tailscale、16年前のSQLite WALリセットバグによるデータベース破損を追跡

Tailscaleは、制御プレーンのシャードで使用するSQLiteデータベースに断続的な破損が発生し、6か月間に19回のインシデントを経験しました。原因は16年前に遡るSQLiteのWALリセットバグで、チェックポイント処理中にページが正しくコピーされず、データの消失や破損を引き起こしていました。TailscaleはSQLite開発者と協力し、フォレンジックテレメトリとトランザクションログのリプレイによりバグを特定し、修正しました。

あるトランザクションによって書き込まれコミットされたデータが、その後のトランザクションからは不可解にも見えなくなっていることが判明しました。エラーも出さずに、書き込みが空中に消えてしまったのです。
  1. simonw

    > 私たちは、レースコンディションをほぼ即座に特定するのに役立ち、将来的に同様のバグを追跡するのにも役立つ、オープンソースのSQLite VFSシムの開発に資金を提供しました。

    これは、企業がオープンソースに資金を提供する興味深い例です。この場合、新しく非常に特化したデバッグツールの開発に費用を支払ったのです。

  2. calmingsolitude

    よく書かれた記事で、読んでいて本当に楽しめました。

    > 単一のGoプロセスがそのデータベースに排他的にアクセスし、それらのテールネットのコントロールプレーンを提供します。この単一ライターデザインは、まさにSQLiteが意図された使い方です。

    この記述から、ライターとチェックポイント処理のロジックが同じデータベース接続上にあると思い込んでしまい、データレースがどのように発生したのか気になりました。しかし、SQLiteのページ[0]のバグの詳細には、複数の接続が開かれている場合にのみ発生し得ると書かれているので、ライターとチェックポインターは別のスレッドにあったに違いありません。

    [0] https://sqlite.org/wal.html#the_wal_reset_bug

  3. anitil

    SQLiteのバグがHNのトップニュースになるというのは、SQLiteについて多くを物語っています。Tailscaleがこれを真剣に受け止め、商用サポート契約を結んだことに感銘を受けました。私も、正確性をこれほど重視する会社で働きたいものです。

  4. andai

    SQLite: 9200万行のテスト

    ダイクストラ: テストはバグの存在を証明できるだけで、不在を証明することは決してできない!

  5. procflora

    とても素晴らしい記事で、SQLiteのバグの説明もありがたく思います。そして、Tailscaleがそれに対して非常にクールな対応をしたこと(VFSシムの費用を負担したことなど)も、とても素晴らしいと思います。

    ただ、彼らをこの道に導いたチェックポイントの頻度についての決定について、もっと詳しく聞きたかったです。おそらく、非常に高速なリカバリのためにWALを小さく保つためでしょう。ネットワーク層にDBMSを挿入することによる悪影響のいくつかを軽減しようとしているのでしょうね。難しい話です。典型的なetcdのスナップショット頻度とどう比較されるのか気になります。

  6. bobtheborg

    素晴らしい読み物でした。彼らがこの話を伝えるために時間を割いてくれて、とても嬉しいです。(そして、営利企業としてSQLiteとサポート契約を結んだことも嬉しいです。この問題が解決された後も、彼らがそれを続けてくれることを願っています。)

  7. bch

    これは本当に、本当に興味深いものでした。なんという勝利の冒険でしょう。

    いくつか(非常に、非常に、非常に細かい)気になった点があります:

    > 私たちは、最後の既知の正常なバックアップにロールバックする(多くのデータを失うことになる)ことも、既知の破損したデータベースを修復する(潜在的にリスクがある)ことも含まない、サービスを復元する方法を望んでいました。

    (強調は私)「潜在的にリスクがある」ではなく「リスクがある」でしょう。その後、「計算されたリスク期間」が始まり、「潜在的に問題がある」となります。

    SQLiteのレポート[0](11.2)では、これをあまり軽視しないでほしかったです。希少性に触れてから技術的な詳細に入る、という形で。私は開発者や元開発者の何人かと親しく、彼らのスキルと業績には最大限の敬意を払っています(そして、個人的に交流のない開発者も同様に優れているという信頼も持っています)。SQLiteという巨大な成果に対する感謝と愛情も持っています。これは世界クラスの仕事です。もしかすると、セクション11.2は私を対象にしたものではなかったのかもしれませんし、私が批判的すぎるのかもしれません。関係者全員に公平に言うと、これほど興味深い問題/修正に対するなんと些細な難癖でしょうか。私のコメントが厄介者にならないことを願っています。

    最後のバグ修正のポイント[1] - うーん。修正をデプロイしてから、非グリーンの状態に溢れるというのは、なんと沈むような気持ちだったでしょう。そして、変更セットに他の変更を「どうせここにいるし」という理由で忍ばせることに対する教訓[2]でもあります。致命的な結果にならなかったのは幸いですが、SQLiteからのリコール[3](他に例をすぐに思い出せませんが)という珍しい事態を引き起こしました。エラーが投げられていたのは、[...]

  8. sandeepkd

    > 私たちのコントロールプレーンでは、高速で一貫性のあるバックアップを実行できるように、チェックポイントプロセスを手動で制御しています。

    > 退屈なテクノロジーを標準的でない方法で実行することはリスクです。

    良い読み物であり、業界が徐々に専門家を失っていることを思い出させてくれました。私はDBAではありませんが、この動作については過去に少なくとも数回、避けるべきものとして聞いたことがあります。専門家が避けていたために文書化される機会がなく、一般の人が触れることもなかった、そういうことの一つです。

この日のほかの記事

2026-08-12