2016-07-07 6 views
0

Я пытаюсь выполнить ALTER TABLE на огромной таблице без блокировки полного доступа. Согласно ALTER TABLE документации:PostgreSQL ALTER TABLE Явная блокировка не работает должным образом

доступ EXCLUSIVE блокировка сохраняется до тех пор явно отметил

Поэтому я следующее:

BEGIN; 
LOCK TABLE MyTable IN SHARE MODE; 
ALTER TABLE MyTable ALTER COLUMN size SET DATA TYPE BIGINT; 
COMMIT; 

Я ожидаю, что это дает мне возможность выполнения запросов SELECT во время обновления. Но на самом деле это не так. Глядя на pg_locks во время операции я обнаружил, что:

SELECT c.relname, l.mode, l.granted, l.pid 
    FROM pg_locks as l JOIN pg_class as c on c.oid = l.relation 
    WHERE relname='MyTable' AND granted IS TRUE; 

relname |  mode   | granted | pid 
----------+---------------------+---------+------ 
MyTable | ShareLock   | t  | 2277 
MyTable | AccessExclusiveLock | t  | 2277 

Так AccessExclusiveLock неожиданно было взят хорошо, и это объясняет, почему мои ВЫБИРАЕТ не висит до конца сделки

я использую PostgreSQL 9.4

ответ

0

Вы, кажется, неверно истолковали , если явно не указано бит.

Это означает, что при наличии различных действий, сгруппированных под ALTER TABLE, для некоторых из них возможно, что блокировки слабее, чем ACCESS EXCLUSIVE, может быть достаточно, и когда дело обстоит именно так, это ясно видно в документации.

Например (от https://www.postgresql.org/docs/9.5/static/sql-altertable.html):

SET СТАТИСТИКИ приобретает ДОЛЯ UPDATE монопольную блокировку.

...

Изменение за атрибута опций приобретает SHARE UPDATE монопольную блокировку.

...

Validation приобретает только SHARE UPDATE монопольную блокировку на данной таблице. Если ограничение внешнего ключа, то замок ДОЛЯ ROW также требуется на столе, на которую ссылается ограничение

Это не означает, что действия, которые требуют ACCESS EXCLUSIVE блокировки (например, изменение типа столбца) может повлиять на предыдущую явную слабую блокировку, захваченную на столе в той же транзакции. Им понадобится замок ACCESS EXCLUSIVE, несмотря ни на что.

+0

О, вот что это значит. Спасибо за объяснение. –