Сведения о блокировке
Управление параллелизмом с несколькими версиями (MVCC) предоставляет соответствующие параметры параллелизма для большинства сценариев. Однако если приложению требуются определенные блокировки, которые управляют именно тем, какие строки затронуты, а также с определенным уровнем блокировки, то явные режимы блокировки позволяют использовать этот точный элемент управления.
В Базе данных Azure для PostgreSQL существует три типа явной блокировки, блокировка на уровне таблицы, блокировка на уровне строк и блокировка на уровне страницы. Начальная транзакция запрашивает блокировку и, если оно принято, запрошенная блокировка становится существующей. Если другая транзакция пытается снять блокировку с теми же данными, блокировка предоставляется, если она не конфликтует с исходной транзакцией.
Например, две транзакции могут запрашивать одни и те же данные одновременно с инструкцией SELECT. Эти запросы будут использовать блокировку ACCESS SHARE, и они оба будут разрешены. В другом сценарии одна транзакция запрашивает данные с помощью инструкции SELECT и блокировки ACCESS SHARE, но в то же время другая транзакция пытается удалить ту же таблицу. Для удаления таблицы требуется блокировка ACCESS EXCLUSIVE, которая не будет предоставлена в этом сценарии.
Блокировки уровня таблиц
Блокировки уровня таблицы получают блокировки для всей таблицы, даже если у них есть инструкция ROW в имени. Блокировка всей таблицы может потребоваться, если сама таблица изменяется или это может быть более эффективным, чем удаление множества блокировок уровня строк.
В База данных Azure для PostgreSQL есть восемь типов блокировки на уровне таблицы, а команды SQL, которые получают эти типы блокировок:
Режим блокировки | Получено пользователем: |
---|---|
ACCESS SHARE | Команда SELECT |
ROW SHARE | Команды SELECT FOR UPDATE и SELECT FOR SHARE |
ROW EXCLUSIVE | Команды UPDATE, DELETE и INSERT |
SHARE UPDATE EXCLUSIVE | Команды ANALYZE, CREATE INDEX CONCURRENTLY, CREATE STATISTICS, COMMENT ON, REINDEX CONCURRENTLY, некоторые команды ALTER INDEX и ALTER TABLE, команда VACUUM (не FULL) |
ОБЩИЙ ДОСТУП | Команда CREATE INDEX (не CONCURRENTLY) |
SHARE ROW EXCLUSIVE | Команда CREATE TRIGGER и некоторые команды ALTER TABLE |
EXCLUSIVE | Команда REFRESH MATERIALIZED VIEW CONCURRENTLY |
ACCESS EXCLUSIVE | DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (не CONCURRENTLY), большинство команд ALTER INDEX и ALTER TABLE и VACUUM FULL |
Каждый тип существующих блокировок блокирует другие запрашиваемые блокировки. В следующей таблице перечислены блокировки, которые блокируют получение других блокировок:
-- | Существующая блокировка ACCESS SHARE | Существующая блокировка ROW SHARE | Существующая блокировка ROW EXCLUSIVE | Существующая блокировка SHARE UPDATE EXCLUSIVE | Существующая блокировка SHARE | Существующая блокировка SHARE ROW EXCL | Существующая блокировка EXCLUSIVE | Существующая блокировка ACCESS EXCLUSIVE |
---|---|---|---|---|---|---|---|---|
Запрашиваемая блокировка ACCESS SHARE | Заблокировано | |||||||
Запрашиваемая блокировка ROW SHARE | Заблокировано | Заблокировано | ||||||
Запрашиваемая блокировка ROW EXCLUSIVE | Заблокировано | Заблокировано | Заблокировано | Заблокировано | ||||
Запрашиваемая блокировка SHARE UPDATE EXCLUSIVE | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | |||
Запрашиваемая блокировка SHARE | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | |||
Запрашиваемая блокировка SHARE ROW EXCLUSIVE | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | ||
Запрашиваемая блокировка EXCLUSIVE | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | |
Запрашиваемая блокировка ACCESS EXCLUSIVE | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано | Заблокировано |
Блокировки уровня строк
Блокировки на уровне строк более детализированные и влияют только на другую транзакцию, доступ к той же строке. Этот тип блокировки повышает параллелизм, но получение и удаление большого количества блокировок отрицательно влияет на производительность. Блокировки на уровне строк автоматически получаются PostgreSQL и не применяются вручную.
Существует четыре типа блокировки на уровне строк в База данных Azure для PostgreSQL, и они получаются в зависимости от того, какие другие типы блокировки необходимо заблокировать:
-- | Существующая блокировка FOR KEY SHARE | Существующая блокировка FOR SHARE | Существующая блокировка FOR NO KEY UPDATE | Существующая блокировка FOR UPDATE |
---|---|---|---|---|
Запрашиваемая блокировка FOR KEY SHARE | Заблокировано | |||
Запрашиваемая блокировка FOR SHARE | Заблокировано | Заблокировано | ||
Запрашиваемая блокировка FOR NO KEY UPDATE | Заблокировано | Заблокировано | Заблокировано | |
Запрашиваемая блокировка FOR UPDATE | Заблокировано | Заблокировано | Заблокировано | Заблокировано |
Блокировка уровня страниц
Блокировки уровня страницы влияют на страницу данных, которая обычно состоит из нескольких строк. Хотя процессы PostgreSQL используют блокировки на уровне страниц, разработчики приложений обычно не требуют этого типа блокировки.
Применение блокировок вручную и просмотр текущих блокировок
Чтобы вручную применить блокировку уровня таблицы, можно использовать команду LOCK с требуемым режимом блокировки. Команда LOCK должна находиться внутри транзакции, и блокировки будут сняты после завершения транзакции. Например:
BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;
Чтобы просмотреть блокировки, которые в настоящее время хранятся в базе данных, используйте pg_locks. Например, для просмотра всех текущих блокировок используется следующая команда:
SELECT * FROM pg_locks;