2011-02-23 4 views
5

以前に選択した〜11.000.000行のPostgreSQLテーブルを他のデータベースから読み込んでいます。私はPythonとpsycopg2を使用しています。プロセス全体が完了するまでにおよそ1.5時間かかります。しかし、〜30分後、私は "接続が予期せず閉じられました"という例外を受け取ります。ソースコードは次のようになります。大きい挿入を実行すると、PostgreSQLの接続が予期せず終了する

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のいくつかの隠された時間制限について非常に心配しています。

+1

私は問題が構成内のあなたのwork_mem変数にある可能性があることです。 AFAIKこの変数は、1つの接続に許可される最大メモリを設定します。ログに何が間違っているかについてのエントリがあることを確認してください – Voooza

+0

しかし、SELECT文は全く機能しません。しかし、私は 'outdb'との接続がゆるいです。 – WolfgangA

+0

'COPY'以上のトランザクションを使用してください。 1回の取引で100件のレコードを実行すると、約110件が得られます。000トランザクションを完了してジョブ全体を完了します。 1台の7400rpmドライブでは、1秒間に120回のコミットしか処理できません(キャッシュが原因でなければ、信頼性が低くなります)。現在の問題はネットワークの問題のように聞こえます。 –

答えて

4

私は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変数を設定できます。

参照:

+0

あなたのリンクに感謝します! – WolfgangA

0

行のmillonsを挿入するために、私は、DBを取り込むに公式guideに目を通すだろうとcopyを使用することを検討してください。

0

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

関連する問題