## Lock 정보 확인 쿼리 ``` sql select locktype, relation::regclass, mode, transactionid tid, pid, granted from pg_catalog.pg_locks where not pid=pg_backend_pid(); ``` - insert 문을 실행했을 때 결과 | locktype | relation | mode | tid | pid | granted | | ------------- | -------- | ---------------- | ----- | ----- | ------- | | relation | 17412 | RowExclusiveLock | NULL | 66376 | TRUE | | relation | 17406 | RowExclusiveLock | NULL | 66376 | TRUE | | virtualxid | NULL | ExclusiveLock | NULL | 66376 | TRUE | | transactionid | NULL | ExclusiveLock | 14144 | 66376 | TRUE | ## Lock 종류 ### Table 수준 Lock | Lock Mode | Access Share | Row Share | Row Exclusive | Share Update Exclusive | Share | Share Row Exclusive | Exclusive | Access Exclusive | |:--------------------------:|:------------:|:---------:|:-------------:|:----------------------:|:-----:|:-------------------:|:---------:|:----------------:| | __Access Share__ | | | | | | | | X | | __Row Share__ | | | | | | | X | X | | __Row Exclusive__ | | | | | X | X | X | X | | __Share Update Exclusive__ | | | | X | X | X | X | X | | __Share__ | | | X | X | | X | X | X | | __Share Row Exclusive__ | | | X | X | X | X | X | X | | __Exclusive__ | | X | X | X | X | X | X | X | | __Access Exclusive__ | X | X | X | X | X | X | X | X | #### Access Share - 일반적인 SELECT 쿼리를 쓰면 얻을 수 있다. - Access Exclusive Lock과 충돌하고 다른 Lock과는 충돌하지 않는다. #### Row Share - [[SELECT FOR SHARE]] 쿼리나 [[SELECT FOR UPDATE]] 쿼리를 쓰면 얻을 수 있다. - Exclusive, Access Exclusive Lock과 충돌한다. #### Row Exclusive - INSERT, UPDATE, DELETE 쿼리를 쓰면 얻을 수 있다. - Share, Share Row Exclusive, Exclusive, Access Exclusive Lock과 충돌한다. #### Share Update Exclusive - [[PostgreSQL VACUUM|VACUUM]](full 제외), [[PostgreSQL ANALYZE|ANALYZE]], CREATE INDEX CONCURRENTLY, CREATE STATISTICS, ALTER TABLE VALIDATE, ALTER TABLE을 수행할 때 얻을 수 있다. - Share Update Exclusive, Share, Share Row Exclusive, Exclusive, Access Exclusive Lock과 충돌한다. #### Share - CREATE INDEX(concurrently 없이)를 수행할 때 얻을 수 있다. - 테이블에서 동시 데이터 변경을 막는다. - Row Exclusive, Share Update Exclusive, Share Row Exclusive, Exclusive, Access Exclusive Lock과 충돌한다. #### Share Row Exclusive - CREATE COLLATION, CREATE TRIGGER를 수행할 때 얻을 수 있다. - 테이블에서 동시 데이터 변경을 막고, 오직 한 세션만 Share Row Exclusive Lock을 얻을 수 있다. - Row Exclusive, Share Update Exclusive, Share, Share Row Exclusive, Exclusive, Access Exclusive Lock과 충돌한다. #### Exclusive - REFRESH MATERIALIZED VIEW CONCURRENTLY를 수행할 때 얻을 수 있다. - Access Share를 제외한 모든 Lock에 충돌한다. #### Access Exclusive - DROP TABLE, TRUNCATE, REINDEX, CLUSTER, VACUUM FULL, REFRESH MATERIALIZED VIEW(concurrently 없이)를 수행할 때 얻을 수 있다. - LOCK TABLE 명령어로 명시적인 Lock을 걸면 Access Exclusive Lock을 얻는다. - 모든 Lock에 충돌한다. ### Row 수준 Lock | Lock Mode | For Key Share | For Share | For No Key Update | For Update | | --------------------- |:-------------:|:---------:|:-----------------:|:----------:| | __For Key Share__ | | | | X | | __For Share__ | | | X | X | | __For No Key Update__ | | X | X | X | | __For Update__ | X | X | X | X | #### For Update - 대상 row에 SELECT, UPDATE, DELETE를 하면 얻을 수 있다. - UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE, SELECT FOR SHARE, SELECT FOR KEY SHARE를 하면 충돌한다. #### For No Key Update - For Update와 같지만 SELECT FOR KEY SHARE와 충돌하지 않는다. - UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE, SELECT FOR SHARE를 하면 충돌한다. #### For Share - For No Key Update와 같지만 ExclusiveLock 대신 SharedLock을 얻는다. - UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE를 하면 충돌한다. #### For Key Share - For Share와 같지만 For No Key Update를 허용한다. - UPDATE, DELETE, SELECT FOR UPDATE를 하면 충돌한다. ### Page 수준 Lock - 공유 버퍼 풀의 테이블 페이지 read/write 접근을 제어한다. - row을 가져오거나 update한 직후에 해제된다. - 일반적인 애플리케이션 개발자는 신경 쓰지 않아도 된다. ### Advisory Lock - 시스템이 락을 강제하는 것이 아니라 애플리케이션에서 락을 걸 수 있는 함수를 제공한다. - 그래서 advisory(권고)이다. #### session 수준 - 명시적으로 Lock을 해제하거나 세션이 종료될 때까지 Lock이 유지된다. #### transaction 수준 - 명시적으로 해제할 수 없고 트랜잭션이 종료될 때 자동으로 해제된다. #db #postgresql