powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Понимание работы механизма блокировок
11 сообщений из 11, страница 1 из 1
Понимание работы механизма блокировок
    #39187494
alexey777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, Друзья!
Изучаю документацию на http://postgrespro.ru. Познакомился с Главой 13. Управление конкурентным доступом.

Хочу уточнить некоторые моменты понимания механизма блокировок.

1. На уровне таблицы.

http://postgrespro.ru/doc/explicit-locking.html "ACCESS SHARE

Команда SELECT получает такую блокировку для таблиц, на которые она ссылается. Вообще говоря, блокировку в этом режиме получает любой запрос, который только читает таблицу, но не меняет её данные."

Я верно понимаю, что при любом Select, независимо от уровня изоляции, накладывается данная блокировка, которую мы можем видеть в pg_locks?

http://postgrespro.ru/doc/explicit-locking.html ROW SHARE

Команды SELECT FOR UPDATE и SELECT FOR SHARE получают такую блокировку для своих целевых таблиц (помимо блокировок ACCESS SHARE для любых таблиц, которые используется в этих запросов, но не в предложении FOR UPDATE/FOR SHARE).

2. На уровне строки.

http://postgrespro.ru/doc/explicit-locking.html FOR UPDATE

В режиме FOR UPDATE строки, выданные оператором SELECT, блокируются как для изменения.
...

Вопрос! Получается, что Команда "SELECT FOR UPDATE" устанавливает две блокировки: блокировка на таблицу ROW SHARE и блокировка на строку FOR UPDATE? И данные блокировки живут до конца транзакции?
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39187511
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexey777Вопрос! Получается, что Команда "SELECT FOR UPDATE" устанавливает две блокировки: блокировка на таблицу ROW SHARE и блокировка на строку FOR UPDATE? И данные блокировки живут до конца транзакции?
Два типа: одна на таблицу `ACCESS SHARE` (на таблицы — табличные блокировки), + на каждую запись `ROW SHARE`.

Все блокировки живут до конца транзакции, кроме тех, которые явно можно "отдать": advisory locks, SAVEPOINT-ы (вот тут я не уверен).

Блокировки не зависят от уровня изоляции.
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39187554
alexey777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, vyegorov!

vyegorovДва типа: одна на таблицу `ACCESS SHARE` (на таблицы — табличные блокировки), + на каждую запись `ROW SHARE`.

Т.е. в документации ошибка?

http://postgrespro.ru/doc/explicit-locking.html Помните, что все эти режимы работают на уровне таблицы, даже если имя режима содержит слово "row"; такие имена сложились исторически.

Что касается `ACCESS SHARE`, то в документации написано, что при установке ROW SHARE на уровне таблицы:

http://postgrespro.ru/doc/explicit-locking.html помимо блокировок ACCESS SHARE для любых таблиц, которые используется в этих запросов, но не в предложении FOR UPDATE/FOR SHARE

т.е. здесь сказано, что `ACCESS SHARE` устанавливается при select, но если будет SELECT FOR UPDATE/FOR SHARE, то блокировка `ACCESS SHARE` установлена не будет, а будет установлена ROW SHARE.

Я так это понимаю. Так написано в документации :), если понимать все дословно, на уровне сериализации :).

vyegorovБлокировки не зависят от уровня изоляции.

Какую тогда роль играют блокировки на каждом уровне изоляции для обеспечения согласованности данных?
Прочитав про работу уровней изоляции для обеспечения согласованности данных, я не нашел там место для блокировок.

Каждый уровень изоляции обеспечивает собственный уровень согласованности данных, не используя блокировки.

Read Committed - операторы DML, если на момент COMMIT версии строк были изменены, вновь попытаются проделать свои манипуляции;
Repeatable read - если на момент фиксации изменений в транзакции (COMMIT) версии строк были изменены, то будет ошибка:
http://postgrespro.ru/doc/transaction-iso.html ОШИБКА: не удалось сериализовать доступ из-за параллельного изменения;
Serializable - все тоже самое, что и в Repeatable read + http://postgrespro.ru/doc/transaction-iso.html он дополнительно отслеживает условия, при которых результат параллельно выполняемых сериализуемых транзакций может не согласовываться с результатом этих же транзакций, выполняемых по очереди.

Т.о. уровни изоляции, используя механизм MVCC полностью обеспечивают согласованность данных в транзакции. С какого "бока припека" тут блокировки? Для чего они нужны? И, в тоже время, они устанавливаются автоматически. Зачем блокировки?
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39187571
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexey777,

1. Это не в док-ии ошибка, это я неправильно выразился.
Любой SELECT накладывет `ACCESS SHARE` на таблицу. SELECT FOR UPDATE накладывает также `ROW SHARE` (хотя мне
думается, что для текущей блокировки просто повышается уровень, т.к. `ROW SHARE` подразумевает `ACCESS SHARE`).
Помимо блокировки на таблицу, SELECT FOR UPDATE наложит блоки на все записи, которые попадут под условия выборки.

2. Блокировки обеспечивают доступ к данным. Уровни изоляции обеспечивают "зону видимости".
Если у вас 2 сессии, обе делают UPDATE одной и той же записи и, скажем, сессия1 пришла первой, то:

- пока не будет фиксации, сессия2 будет ждать при любой изоляции (это обеспечивают блокировки)
- после фиксации, в READ COMMITTED, сессия2 перечитает новую версию строки, применит предикаты и либо перезапишет
значение, либо просто пропустит
- в REPEATABLE READ и SERIALIZABLE будет ошибка сериализации

Блокировки тут с того бока, что не важно какая у вас изоляция — данные должны меняться последовательно, а то будет бардак.
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39187747
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexey777,

авторТ.о. уровни изоляции, используя механизм MVCC полностью обеспечивают согласованность данных в транзакции. С какого "бока припека" тут блокировки? Для чего они нужны? И, в тоже время, они устанавливаются автоматически. Зачем блокировки?

Например чтобы вы во время выполнения select Из таблицы не могли внести в нее alter и изменить структуру или вообще дропнуть таблицу.
Тут же все разобрано какие команды какие уровни локов требуют
http://www.postgresql.org/docs/9.5/static/explicit-locking.html
и что чему мешает.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39187800
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexey777,
надо вообще изначально понимать, что это не "блокировки", термин неверный, подразумевает, что кто-то кого-то блокирует.
Лучше называть это "лок", или "замок", или еще как-то, "барьер" например.
это внутренние структуры сервера бд, с помощью которых ограничивается доступ к определенным структурам данных, из создание может блокировать кого-то, но может и не приводить к блокированию.
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39187805
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Bogukalexey777,

авторТ.о. уровни изоляции, используя механизм MVCC полностью обеспечивают согласованность данных в транзакции. С какого "бока припека" тут блокировки? Для чего они нужны? И, в тоже время, они устанавливаются автоматически. Зачем блокировки?

Например чтобы вы во время выполнения select Из таблицы не могли внести в нее alter и изменить структуру или вообще дропнуть таблицу.
Тут же все разобрано какие команды какие уровни локов требуют
http://www.postgresql.org/docs/9.5/static/explicit-locking.html
и что чему мешает.

--
Maxim Boguk
www.postgresql-consulting.ru
я думаю, пассажыр не понимает, что такое мвсс в большинстве версионников. он думает что может быть 2 и более незакомиченных версии одной записи--писи одновременно. я как--то пытался думать эту версию мвсс, она мне не понравилась. хотя показалась реализуемой.

пассажыр, в большинстве версионников реализован read commited -- пишущий не лочит только читателей. писатели же встают друг за другом в очередь, что реализовано посредством блокировок. именно с такого бока, что очередь выгоднее массовых отказов вида "пока вы тут телились, кто-то изменил вашу запись" (что происходит на repeatable и serializable -- но уже в более глубоком смысле -- "пока вы даже не доступались, она уже изменилась"). или прочих следствий шизофрении с массовыми версиями одной записи.

поэтому людей, не желающих работать с очередями надо прямиком отсылать к более другим СУБД.
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39189302
alexey777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо.

В голове моей прояснилось :).

Я верно понимаю, что команда SELECT FOR UPDATE накладывает блокировку с гранулярностью Таблица - ROW SHARE и блокировку FOR UPDATE с гранулярностью Строка. В матрице совместимости блокировок ROW SHARE не конфликтует сама с собой. Тогда как FOR UPDATE не совместима сама с собой - т.о. получается, что:

qwwqписатели же встают друг за другом в очередь

или (тоже как синоним фразы)

vyegorovпока не будет фиксации, сессия2 будет ждать при любой изоляции (это обеспечивают блокировки)

Запись ждет запись :).

Есть здесь очень важный нюанс: блокировка произошла на уровне записи, а не таблицы - нет избыточной блокировки. Я верно понимаю :)?
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39189360
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexey777Спасибо.

В голове моей прояснилось :).

Я верно понимаю, что команда SELECT FOR UPDATE накладывает блокировку с гранулярностью Таблица - ROW SHARE и блокировку FOR UPDATE с гранулярностью Строка. В матрице совместимости блокировок ROW SHARE не конфликтует сама с собой.
Тогда как FOR UPDATE не совместима сама с собой.
Есть блокировки 2-х типов. Табличные применяются в любом запросе.
ROW SHARE не конфликтует сама с собой для того, чтобы 2 разных сессии могли делать SELECT FOR UPDATE разным частям таблицы без ожидания. Сама ROW SHARE на всю таблицу нужна, чтобы паралельные сессии не могли перестроить таблицу (вроде CLUSTER) или грохнуть её.
Блокировка FOR UPDATE на запись обеспечивает сериализацию одинаковых SELECT FOR UPDATE запросов, которым нужна одна и та же запись.

alexey777Есть здесь очень важный нюанс: блокировка произошла на уровне записи, а не таблицы - нет избыточной блокировки. Я верно понимаю :)?
Блокировка и на уровне таблицы (обязательно), и на уровне записи (обязательно для SELECT FOR UPDATE).
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39190138
alexey777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov, Спасибо, согласен.

А вот если мы производим Insert, Update, то какие тогда накладываются блокировки? ROW EXCLUSIVE - блокировка на уровне таблицы, а вот на уровне строк будут ли какие-либо блокировки?

Потому, как если больше блокировок не будет, то очереди не будет, т.к. ROW EXCLUSIVE совместима сама с собой :).
...
Рейтинг: 0 / 0
Понимание работы механизма блокировок
    #39190249
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexey777,

Ну так такой же механизм.
Табличные блокировки нужны чтобы конфликтующие операции не производились одновременно.
ROW EXCLUSIVE запрещает создание индексов, соответственно, если вы делаете индекс — DML операции невозможны.
(Потому и появилась CREATE INDEX CONCURRENTLY).

А с записями всё тоже самое — любой "писатель" накладывает блок на записи, к которыы он прикасается.
В случае с INSERT блокировки конфликтовать не могут, т.к. другие сессии ещё не знают о новых записях.

Однако INSERT блокирует уникальные индексы (если есть). Не целиком, а конкурентные значения — 2 параллельные сессии могут вставить 2 разных значения в уникальныю колонку без проблем.

Я не до конца понимаю эту часть, (документация говорит только об таблицах), небольшой опыт сделал — таблица с первичным ключем, 2 сесии вставляют запись с одним и тем же ID, транзакции открыты.
Первая держит:
- AccessShareLock на `pg_locks` (это я смотрю блоки)
- RowExclusiveLock на таблицу
- ExclusiveLock на свою тразанзакцию (в моём случае это 1832)
- ExclusiveLock на виртуальную транзакцию, такие создаются при обычных SELECT-ах чтобы счётчик транзакций не улетал

Вторая держит:
- RowExclusiveLock на таблицу и на индекс
- ExclusiveLock на свою транзакцию (у меня 1833)
- ExclusiveLock на виртуальную транзакцию
и ждёт ShareLock на транзакцию (1832, первую).

Получается, что INSERT добрался до индекса и увидел там значение, которое он должен "проверить" на уникальность, но это значение "заперто" транзакией (пока не зафиксированой). И вот INSERT встаёт в очередь за транзакией.
Таким образом тут нету строчных блокировок, есть ожидание незавершенной транзакции.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Понимание работы механизма блокировок
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]