Итак, я запутался в обработке ограничений внешних ключей в 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