やっと簡単な問題だ。初期ダウンロードのような長い操作中に発生しうる原因が見えた。TryLockのバグはDB関連の問題とは無関係だ。修正はtest8に含まれる。
32ビットLinux上で、絶え間ないリクエストの連続フラッドを送りつけることで、db::open/close例外を3回再現できた。wallet.datデータベースを定期的に閉じてフラッシュするだけでもdb::close例外が発生するようだ。Linuxではウォレットフラッシュ機能を無効にする。Linux上では、終了する準備ができるまでデータベースハンドルを閉じないようにする。これを無効にしてからは、今のところ例外は発生していない。
初期ブロックダウンロードの秩序立った実装も進めている。すべてのブロックを一度にリクエストする素朴な方法ではなく、一度に500件ずつバッチでリクエストするようにする。こうすることで、リトライタイムアウトの前にブロックを受信できるため、実際に受信できなかったり遅すぎたりしない限り、他のノードにリクエストすることはなくなるはずだ。変更はリクエストを受ける側にあるため、初期ブロックダウンロードの相手が新しいバージョンのノードになるまで、この機能は見えない。
test8を送る前にもう少しテストを続ける。
Liberty Standard の書き込み:
test7で新しいデータディレクトリから開始しました。ブロックのダウンロードがずっと速くなりました。Linuxビルドでは以前数分かかっていたところ、約15秒しかかかりませんでした。ブロックのダウンロード中に以下のメッセージがターミナルに表示されて一度クラッシュしました。
../include/wx/thrimpl.cpp(50): assert “m_internal” failed in TryLock(): wxMutex::TryLock(): not initialized [in child thread] Trace/breakpoint trap
ログファイルを添付しましたが、bitcoinを再起動する前にバックアップするのを忘れたため、ログファイルのどの時点でクラッシュしたかわかりません。
幸い、まだセグメンテーションフォルトには遭遇していません。以前のビルドではセグメンテーションフォルトの頻度がかなりばらつきがあったので、引き続き実行して問題があればお知らせします。
2009年11月17日(火) 午前5:41、Satoshi Nakamoto <satoshin@gmx.com mailto:satoshin@gmx.com> の書き込み:
test 7: 念のため、実行前にデータディレクトリをバックアップしてください。 Db::open/Db::close「Bad file descriptor」例外の回避策です。 初期ブロックダウンロードも高速化される可能性があります。回避策は、 データベースハンドルを開いたままプログラムの実行中ずっと保持しておくことで、 実際これはより一般的なやり方でもあります。常に閉じたり開いたりしなければ、 エラーが発生する機会がなくなるはずです。 唯一の例外はwallet.datで、書き込み完了後にトランザクションログを datファイルにフラッシュするために閉じるようにしています。これにより、 datファイルが単体で有効になります。Bitcoinの実行中に誰かがバックアップを 取った場合、データベースのトランザクションログなしでもそれ自体で 有効なwallet.datを取得できます。 これはデータベース処理の再構成なので、新たなデッドロックが 見つかるかもしれません。通常、デッドロックが発生すると、UIの再描画が 止まるか、まだGeneratingと表示されているにもかかわらずCPUを 使用しなくなります。
出典:COPA対ライト裁判の証言の一環として、2024年2月にマルッティ・マルミによりGitHubで公開。完全な書簡アーカイブはmmalmi.github.io/satoshi/で閲覧可能。