그래서 Postgresql의 외래 키 제약 조건 처리에 대해 혼란스러워하고 있습니다. (버전 8.4.4).Postgresql : 외래 키 제약 조건 평가에서 암시 적 잠금 획득
우리는 약간 아래에 익명 테이블의 몇 가지를 가지고 :
device:
(id, blah, blah, blah, blah, blah x 50)…
primary key on id
whooooole bunch of other junk
device_foo:
(id, device_id, left, right)
Foreign key (device_id) references device(id) on delete cascade;
primary key on id
btree index on 'left' and 'right'
은 그래서 일부 쿼리를 실행하는 두 개의 데이터베이스 창에 착수했다.
db1> begin; lock table device in exclusive mode;
db2> begin; update device_foo set left = left + 1;
db2 연결 블록.
device_stuff에서 '왼쪽'열의 업데이트가 장치 테이블의 활동에 영향을 받는다는 것은 이상한 것 같습니다. 하지만 그것은. 사실, 나는 DB1로 돌아갈 경우 :
db1> select * from device_stuff for update;
*** deadlock occurs ***
pgSQL의 로그는 다음과 같습니다
blah blah blah deadlock blah.
CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."device" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF X: update device_foo set left = left + 1;
나는 두 가지 문제를 가지고 가정 : 첫 번째는 내가 이해하지 않는다는 것입니다 이러한 종류의 잠금이 발생하는 정확한 메커니즘. 문을 호출하는 어떤 종류의 잠금을 보려면 pg_locks를 쿼리하는 몇 가지 유용한 쿼리가 있지만 난 update device_foo
명령을 단독으로 실행하면이 특정 종류의 잠금을 관찰 할 수 없었습니다. (아마도 나는 잘못된 것을하고 있습니다.) 또한 외래 키 제약 조건 검사의 잠금 획득 동작에 대한 문서를 찾을 수 없습니다. 내가 가진 것은 로그 메시지뿐입니다. 이 행을 변경하면 외래 키가있는 모든 테이블에서 업데이트 잠금이 획득됩니다.
두 번째 문제는 그런 일이 발생하지 않도록하는 방법을 찾고 싶습니다. 실제 응용 프로그램에서 가끔 교착 상태가 발생합니다. 나는 device_foo
에있는 모든 행에 영향을주는 큰 업데이트 문을 장치 테이블에서 큰 잠금을 획득하지 않고 실행할 수 있기를 바랍니다. (이 접근이 device
테이블에서 벌어지고 많은, 그리고 그것을 얻기 위해 비싼 잠금의 종류입니다.)
하지만 외래 키 제약 조건을 확인해야하는 이유는 무엇입니까? 외래 키 열을 변경하지 않습니다. – fennec