3

本番環境で実行されている、安定した Web ベースのシングル スレッド/プロセスの perl アプリケーションが、システムの負荷が高い場合にのみ、このエラーを断続的にスローし始めました。根本原因を特定できません。

Usage: DBD::Pg::db::DESTROY(dbh) during global destruction

誰でもこのエラーの説明を提供できますか? Perl がシャットダウン前にクリーンアップしているときに、DESTROY が引数 (self?) なしで呼び出されると、Pg.sx からスローされるようです。(Google 経由で古いソース コードにそのメッセージが表示されますが、私たちのバージョンには表示されません。) 環境:

  • OS: FreeBSD 8.3-STABLE
  • Perl v5.14.2
  • DBD::Pg v2.19.3
  • PostgreSQL: v9.2.3
4

2 に答える 2

4

これが暗闇でのショットです。

DBI データベース ハンドルは通常、他のオブジェクトと同じように破棄されます。何も参照されていない場合です。ただし、ハンドルが自然に破棄されるのを妨げる可能性があります。

  • ハンドルはパッケージグローバルです
  • Perl が自動的に解放できない循環参照のハンドル フォームの一部

これが発生すると、オブジェクトは「グローバル破壊」の一部として破壊されます。これは、基本的にすべてを undefDESTROYし、実際にはランダムな順序で呼び出すだけです。これが、誤ったエラーの原因となっている可能性があります。

まず、スクリプトの最初と最後で DB ハンドルを列挙してみて、最後までまだ使用されているものがあるかどうかを確認します。このコード スニペットを参照してください。

sub show_child_handles {
    my ($h, $level) = @_;
    printf "%sh %s %s\n", $h->{Type}, "\t" x $level, $h;
    show_child_handles($_, $level + 1)
        for (grep { defined } @{$h->{ChildHandles}});
}

my %drivers = DBI->installed_drivers();
show_child_handles($_, 0) for (values %drivers);

オブジェクトがまだ使用されている理由がわからない場合は、Devel::Cycleをいくつかの大きなデータ構造で使用してそれらを見つけることができます。

DBI のトレース機能も便利です。スクリプトを実行する前にエクスポートDBI_TRACE=2すると、ハンドルが作成または破棄されるたびにログに記録されます。

于 2013-02-22T22:12:52.130 に答える
3

私の場合、サーバーのアップグレード後に発生し始めたため、PostgreSql/Perl/DBD バージョン固有のエラーのようです。

このエラーは、データベース ハンドルを明示的に破棄していないすべてのスクリプトで突然発生し始めました。追加する$dbx->disconnect()と解決しました。

更新: この回避策は、一部のスクリプトでのみエラーを修正しました。それ以外では、データベース ハンドルを明示的に破棄してもエラーが持続します。

于 2015-03-11T08:26:53.343 に答える