sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLのロックメカニズムのバグまたはメカニズムの誤解

    バグはありませんし、あなたが何かを誤解しているとは思いません。パズルのいくつかのピースが欠けているだけです。

    外部キーは、行レベルのロックを使用して内部的に実装されます。 Postgres 8.1から9.2まで、参照テーブル(apples)を更新するたびに この場合)、SELECT FOR SHAREを実行するクエリが実行されます。 参照されるテーブル(trees )。そのため、SELECT FOR UPDATE 最初のトランザクションで、SELECT FOR SHAREをブロックします 2番目のトランザクションの参照整合性。これが2番目のコマンドでブロックを引き起こす原因です。

    今、私はあなたが叫ぶのを聞きます。最初のコマンドではなく、2番目のコマンドでブロックされるのはなぜですか?説明は本当に簡単です。これは、内部のSELECT FOR SHAREをスキップする単純な最適化があるためです。 キーが変更されていないとき。ただし、これは単純化されており、タプルを2回更新しても、元の値を追跡するのが難しいため、この最適化は実行されません。したがって、閉塞。

    また、なぜこれが9.2までだと言ったのか不思議に思うかもしれません--- 9.3とは何ですか?主な違いは、9.3ではSELECT FOR KEY SHAREを使用することです。 、これは新しい、より軽いロックレベルです。それはより良い並行性を可能にします。 9.3で例を試し、SELECT FOR UPDATEも変更した場合 SELECT FOR NO KEY UPDATE (これはSELECT FOR UPDATEよりも軽いモードです つまり、タプルを更新する可能性がありますが、主キーを変更せず、削除しないことを約束します)、ブロックされないことがわかります。 (また、参照されている行でUPDATEを試すことができます。主キーを変更しないと、ブロックされません。)

    この9.3のものは、本当に http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0ac5ad5134f2769ccbaefec73844f8504c4d6182 そして、それはかなりクールなハックだったと思います(そのようなことを気にするなら、コミットメッセージにはもう少し詳細があります)。ただし、9.3.4より前のバージョンは使用しないでください。パッチが非常に複雑であるため、いくつかの重大なバグが見過ごされ、最近修正されたばかりです。




    1. java.net.ConnectException:localhost / 127.0.0.1(ポート80)への接続に失敗しました:接続に失敗しました:ECONNREFUSED(接続が拒否されました)

    2. CloudSQLでの証明書の検証

    3. Oracleクエリの最適化

    4. ec2 bitnamiで(2002、ソケット'/tmp/mysql.sock'(2)を介してローカルMySQLサーバーに接続できない)を修正する方法は?