web-dev-qa-db-ja.com

PostgreSQLでACCESS EXCLUSIVE LOCKが必要なのはなぜですか?

私はPostgreSQLが同時実行制御のために複数のロックモードを提供することを知っています。私が彼らのドキュメントを読んだとき、どのような場合でもACCESS EXCLUSIVEロックが必要な理由がわかりません。 EXCLUSIVEロックとACCESS EXCLUSIVEロックの唯一の違いは、ACCESS EXCLUSIVEロックがテーブルからの読み取りを許可しないことです。

でも、人が読めるのはいいことじゃないですか。どのような場合に、ユーザーが読書できないようにする必要がありますか?ドキュメントでは、通常DROP TABLEなどがACCESS EXCLUSIVEロックを使用することがわかりましたが、なぜですか?おそらく、テーブルをドロップしたときに、データを読み込もうとしたときにすでにデータが部分的に失われているため、結果が破損するのではないかと考えていました。しかし、Postgresのすべてがトランザクションであるため、DROP TABLEはコミットするまで有効になりません。だから私の推測は間違っているはずです。

私はまだ混乱しています。 EXCLUSIVEロックと比較すると、ACCESS EXCLUSIVEロックが再度必要なのはなぜですか?私の推測では、ACCESS EXCLUSIVEロックをEXCLUSIVEロックに置き換えてもPostgreSQLは動作しなくなると思います。それは時々人々が他人に読んでほしくないことです。私は何か見落としてますか?

6
Matt Li

documentation を確認すると、このタイプのロックを取得する操作のリストが表示されます。

DROP TABLETRUNCATEREINDEXCLUSTERVACUUM FULL、およびREFRESH MATERIALIZED VIEWCONCURRENTLYなし)によって取得)コマンド。 ALTER TABLEの多くの形式も、このレベルでロックを取得します。

これらはすべて物理的に(再)行を移動しているため、これらの間の読み取りは少なくとも非常に予測不可能です。

トランザクションについて言えば、テーブルから読み取りを開始し、別のプロセスが少し後でそれを削除することを決定した場合、後者は読み取りが完了するまで待機する必要があります。テーブルをロックして削除します。逆の場合は、トランザクションを削除することからコミットするまで待機した後で、読み取りが失敗するだけです。

PostgreSQLが削除されるテーブルからの読み取りを許可した場合、それは2つのことを意味します。 1つは、私が間違っていない限り、 READ UNCOMMITTED 分離レベルが存在したことです。それを選択することはできますが、実際にはREAD COMMITTEDです。つまり、他のトランザクションの中間状態を確認できるトランザクションはありません。もう1つは、ご想像のとおり、必要なデータの一部のみが返される可能性があることです。これは予期しない動作を引き起こす可能性があり、それはデータベースシステムに必要な最後のことです。

さらに、CLUSTERVACUUM FULLは2つのファイル間でデータを移動しています。どのファイルで行を追跡するかをどのように決定できますか?

全体として、場合によっては、データの読み取りはそれほど緊急ではありません。または、DROP TABLEおよびTRUNCATEの場合、それほど緊急ではありませんもう

11
dezso