2016-01-20 11 views
7

非常に大きなRedshiftデータベースには、何十億行ものHTTP要求データが含まれています。Redshift:表のシリアライズ可能な隔離違反

  • ip_address
  • city
  • state
  • country

私は一回実行しているPythonのプロセスを持っている:

私は、テーブルには、いくつかの重要なフィールドを持っているrequestsと呼ばれていすべてのdをつかむ日(地理情報/国/国の情報はありません)がまだジオコードされていない行を検索し、GoogleのジオコーディングAPI経由で各IPアドレスをジオコードすることを試みます。

for ip_address in ips_to_geocode: 
    country, state, city = geocode_ip_address(ip_address) 
    execute_transaction(''' 
     UPDATE requests 
     SET ip_country = %s, ip_state = %s, ip_city = %s 
     WHERE ip_address = %s 
    ''') 

このコードを実行すると、私は多くの場合、以下のようなエラーを受け取ります:

このプロセスは、(擬似コード)は次のようになります

psycopg2.InternalError: 1023 
DETAIL: Serializable isolation violation on table - 108263, transactions forming the cycle are: 647671, 647682 (pid:23880) 

私は私が他の持っているためであると仮定しています私のUPDATEステートメントを実行しようとすると、すべて行を更新したい行を選択することができません。

私の質問は次のとおりです。これらのレコードを正常に更新して定期的に失敗することはできますか?

答えて

3

コードがシリアル化可能な分離レベルのRedshiftに違反しています。開いているトランザクションをすべて閉じる前に、コードが同じテーブルで複数のトランザクションを開こうとしていないことを確認する必要があります。

これは、オープントランザクションがクローズされるまで、他のトランザクションが更新用のテーブルにアクセスできないように、各トランザクションでテーブルをロックすることで実現できます。あなたのコードが(同期または非同期で)どのように構築されているかはわかりませんが、トランザクションが終了するまで、各ロックが他の人に強制的に待機させるため、実行時間が長くなります。

を参照してください:あなたが同じテーブルの上に2回目の更新を行う際にhttp://docs.aws.amazon.com/redshift/latest/dg/r_LOCK.html

0

は、新しいセッションを開始するいずれか、またはあなたのトランザクションが完了すると「コミット」する必要があります。

更新を開始する前にset autocommit = onと書くことができます。

0

はちょうど私のコードでも同じ問題を持って、私はそれを修正する方法のthats:

まず物事を最初に、このエラーコードは、あなたが赤方偏移で同時操作をやろうとしていることを意味することを知って良いです。たとえば、あなたがこの種のエラー(私の場合)を取得する場合があります。

良いニュースは:赤方偏移操作をシリアライズする簡単な方法があります! LOCKコマンドを使用するだけです。ここにはredshift LOCK commandのAmazonドキュメントがあります。基本的には、前の操作が閉じられるまで次の操作を待機させます。このコマンドを使用すると、スクリプトは自然に少し遅くなります。

最終的に私にとって実際的な解決策は次のとおりです。クエリメッセージの前にLOCKコマンドを挿入しました(同じ文字列内に ';'で区切ります)。このような何か:

LOCK table_name; SELECT * from ...

そして、あなたが行ってもいいはずです!それがあなたを助けることを願っています

関連する問題