13. clustered のコードを読む5 - PostgreSQL のソースコードを読む

少し脱線してロックについて見て回る。
ロックが獲得されるのは

  • ユーザーが明示的にロックする
    • LOCK コマンド
  • Query や transaction に付随して DBMS が裏でロックする

の2つある。


ロックの種類とその意味は以下。
http://www.postgresql.jp/document/pg721doc/reference/sql-lock.html

  • ACCESS SHARE
  • ROW SHARE
  • ROW EXCLUSIVE
  • SHARE UPDATE EXCLUSIVE
  • SHARE
  • SHARE ROW EXCLUSIVE
  • EXCLUSIVE
  • ACCESS EXCLUSIVE


これはコード上は lock.h で定義されている。

#define AccessShareLock         1       /* SELECT */
#define RowShareLock            2       /* SELECT FOR UPDATE/FOR SHARE */
#define RowExclusiveLock        3       /* INSERT, UPDATE, DELETE */
#define ShareUpdateExclusiveLock 4      /* VACUUM (non-FULL),ANALYZE, CREATE
                                         * INDEX CONCURRENTLY */
#define ShareLock               5       /* CREATE INDEX (WITHOUT CONCURRENTLY) */
#define ShareRowExclusiveLock   6       /* like EXCLUSIVE MODE, but allows ROW
                                         * SHARE */
#define ExclusiveLock           7       /* blocks ROW SHARE/SELECT...FOR
                                         * UPDATE */
#define AccessExclusiveLock     8       /* ALTER TABLE, DROP TABLE, VACUUM
                                         * FULL, and unqualified LOCK TABLE */


コード上でロックを獲得するには heap_openrv や heap_open の第2引数に lock mode を渡せば良い。

cluster コマンドにおけるロック

cluster コマンドでは、relation と index のどちらとも AccessExclusiveLock が使われている。

  • ALTER TABLE
  • DROP TABLE
  • VACUUM FULL

などでも使われているロックで、ロックを獲得したプロセス以外はテーブルに触れなくなる。


cluster コマンドでこのロックが使われているのは、恐らくテーブルのコピーが行われるから。テーブルコピー中に、コピー元が ALTER TABLE, DROP TABLE, VACUUM FULL されると困るのだろう。
逆に言えば、上記コマンドを CLUSTER 中に発行しないならば、ExclusiveLock で済むはずなので、CLUSTER 化中に select できるんだが。
上記の方法で unsafe な CLUSTER コマンドを実装するのはどうなのだろうか。

todo

  • MemoryContext
  • cluster にもどり heap の copy など