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