6

別のデータベースから以前に選択された〜11.000.000行をPostgreSQLテーブルに入力しています。Python と psycopg2 を使用しています。プロセス全体が完了するまでに推定 1.5 時間かかります。ただし、約 30 分後に「接続が予期せず閉じられました」という例外が発生します。ソースコードは次のようになります。

incursor = indb.cursor()
incursor.execute("SELECT ...")
indb.commit() # (1) close transaction
outcursor = outdb.cursor()
rows = 0
for (col1, col2, col3) in incursor: # incursor contains ~11.000.000 rows
    outcursor.execute("INSERT ...", (col1, col2, col3)) # This fails after ~30 minutes
    row += 1
    if row % 100 == 0: # (2) Write data every 100 rows
         outcursor.close()
         outdb.commit()
         outcursor = outdb.cursor()
incursor.close()
outcursor.close()
outdb.commit()

開いているトランザクションに最大 30 分の上限時間があるか、カーソルに保留中の挿入の上限があると仮定して、失敗した最初の試行の後に挿入(1)しました。(2)この仮定はどれも正しくなく、エラーは別の場所にあるようです。

両方のデータベースは、ホストからのポート転送を介して接続する VirtualBox マシンに格納されています。ホストマシンでプログラムを実行します。

どちらのデータベースもテスト目的のみであり、管理する他の接続はありません。psycopg2これを回避するには問題を書き直す必要があるかもしれませんが、他の場所で非常に時間のかかる挿入が必要なので (約数日間実行されます)、または PostgreSQLの隠れた時間制限について非常に心配しています。

4

3 に答える 3

5

postgresql自体にそのような「隠された」タイムアウトがあることは知りません。PostgreSQL には がありますがstatement_timeout、ヒットした場合ERROR: canceling statement due to statement timeoutはサーバー ログに が記録されます (キャンセルされたステートメントもログに記録されます)。psycopg2 について話すことはできません。関連するものがないか、サーバーログを必ず確認してください。

多分それはネットワークの問題ですか?実行時間の長いステートメントは、長時間アイドル状態のままの TCP 接続になります。おそらく、ポート フォワーディングによって、30 分以上アイドル状態の接続がパージされているのではないでしょうか? TCP 接続がキープアライブを使用していない可能性があります。Postgresql には、TCP キープアライブ (tcp_keepalives_interval など) を調整するための設定がいくつかあります。それらが実際に有効になっていることを確認するために、カーネル/ネットワーク構成も行う必要がある場合があります。

たとえば、ここで自分のマシンに接続しようとしましたが、tcp_keepalives_intervalデフォルトは 7200 で、これは 2 時間です。ポート フォワーディングが 30 分後に切断された場合、このデフォルトでは機能しません。クライアント接続文字列で使用される設定をオーバーライドするか (conninfo 文字列を直接変更できると仮定)、ユーザー/データベース プロパティまたは postgresql.conf で GUC 変数を設定できます。

見る:

于 2011-02-23T11:11:24.733 に答える
0

何千もの行を更新するdjango管理コマンドがあります。しばらくすると、同じエラーが表示されます。メモリ使用量が限界を超えていると思います。ただし、コマンドでトランザクションを手動で制御する方法がわかりません。

于 2011-07-30T17:38:42.897 に答える
0

何百万もの行を挿入するには、dbの作成に関する公式ガイドを調べて、 copyの使用を検討します。

于 2011-02-23T11:14:01.303 に答える