Объясните роль блокировок намерений в MySql InnoDB.

интервью задняя часть база данных MySQL Байду DBA

предисловие

Поддержка InnoDB多粒度锁(multiple granularity locking), который позволяет行级锁и表级锁сосуществовать, иблокировка намеренийодин из них表锁.

Замки намерения

Следует подчеркнуть, что блокировка намерения является своего рода不与行级锁冲突表级锁, этот момент очень важен. Существует два типа блокировки намерений:

  • Общая блокировка намерения(преднамеренная общая блокировка, IS): транзакция намеренно добавляет несколько строк в таблицуобщий замок(S-замок)
    -- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
    SELECT column FROM table ... LOCK IN SHARE MODE;
    
  • эксклюзивная блокировка намерения(намеренная монопольная блокировка, IX): транзакция намеренно добавляет определенные строки в таблицу.эксклюзивный замок(Х замок)
    -- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
    SELECT column FROM table ... FOR UPDATE;
    

который:意向锁是有数据引擎自己维护的,用户无法手动操作意向锁, перед добавлением общей/эксклюзивной блокировки к строке данных InooDB сначала получит соответствующую блокировку намерения таблицы данных, в которой находится строка данных.

Проблемы, решаемые блокировками намерения

Давайте сначала посмотрим на описание значения блокировки намерения в энциклопедии Baidu:

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

представьте себе такуюusersповерхность:MySql,InnoDB,Repeatable-Read:users(id PK, имя)

id name
1 ROADHOG
2 Reinhardt
3 Tracer
4 Genji
5 Hanzo
6 Mccree

Транзакция A Получает эксклюзивный замок на ряд и не совершает:

SELECT * FROM users WHERE id = 6 FOR UPDATE;

Транзакция B хочет получитьusersБлокировка стола для стола:

LOCK TABLES users READ;

Из-за разделяемых блокировок и эксклюзивных блокировок互斥, поэтому транзакция B находится в паре представленийusersПри добавлении разделяемой блокировки к таблице необходимо убедиться, что:

  • Ни одна другая транзакция в настоящее время не удерживает монопольную блокировку таблицы пользователей.
  • Ни одна другая транзакция в настоящее время не удерживает монопольную блокировку какой-либо строки в таблице пользователей.

Чтобы определить, выполнено ли второе условие, транзакция B должна обеспечитьusersИсходя из того, что для таблицы нет монопольной блокировки, проверьте, имеет ли каждая строка в таблице монопольную блокировку. Очевидно, что это очень неэффективная практика, но сблокировка намеренийПосле этого все по-другому:

Совместимый мьютекс блокировок намерений

Как блокировка намерения решает эту проблему? Во-первых, нам нужно знать мьютексы совместимости между блокировками намерений:

Общая блокировка намерений (IS) Преднамеренная эксклюзивная блокировка (IX)
Общая блокировка намерений (IS) совместимый совместимый
Преднамеренная эксклюзивная блокировка (IX) совместимый совместимый

которыйБлокировки намерений совместимы друг с другом, эммм... Тогда в чем смысл твоего существования?

Хотя блокировки намерений совместимы со своими собратьями, они будут совместимы с обычными блокировками.Эксклюзивный/общий замокВзаимоисключающий:

Общая блокировка намерений (IS) Преднамеренная эксклюзивная блокировка (IX)
Общий замок(и) совместимый взаимоисключающий
Эксклюзивный замок (X) взаимоисключающий взаимоисключающий

Примечание. Эксклюзивные/разделяемые блокировки здесь относятся к блокировкам таблицы! ! ! Блокировки намерения не являются взаимоисключающими с разделяемыми/исключительными блокировками на уровне строк! ! !

Теперь давайте вернемся к только чтоusersПример таблицы:

事务 AПолучил эксклюзивную блокировку строки без фиксации:

SELECT * FROM users WHERE id = 6 FOR UPDATE;

В настоящее времяusersНа столе два замка:usersна столеэксклюзивная блокировка намеренияс идентификатором 6 в строке данныхэксклюзивный замок.

Транзакция B хочет получить общую блокировку таблицы пользователей:

LOCK TABLES users READ;

В настоящее время事务 BОбнаружить транзакцию АusersТаблицаэксклюзивная блокировка намерения, можно узнать, что事务 AНеизбежно удерживайте некоторые строки таблицыэксклюзивный замок,Так事务 BправильноusersЗапрос на блокировку таблицы будет исключен (заблокирован) без необходимости определять наличие монопольной блокировки для каждой строки данных в таблице.

Параллелизм блокировок намерений

Это включает в себя то, что я уже много раз подчеркивал:

Блокировки намерения не являются взаимоисключающими с разделяемыми/исключительными блокировками на уровне строк! ! !
Блокировки намерения не являются взаимоисключающими с разделяемыми/исключительными блокировками на уровне строк! ! !
Блокировки намерения не являются взаимоисключающими с разделяемыми/исключительными блокировками на уровне строк! ! !

Важные слова должны быть выделены жирным шрифтом три раза, поэтому блокировки по намерениям не повлияют на параллелизм нескольких транзакций при добавлении монопольных блокировок к разным строкам данных (в противном случае мы можем напрямую использовать обычные блокировки таблиц).

Наконец, давайте расширим пример таблицы пользователей выше, чтобы обобщить роль блокировок по намерению (может быть много разных блокировок в процессе блокировки части данных до освобождения, но здесь мы сосредоточимся только на блокировках по намерению):

id name
1 ROADHOG
2 Reinhardt
3 Tracer
4 Genji
5 Hanzo
6 Mccree

事务 AПолучить ряд первымэксклюзивный замок, не представил:

SELECT * FROM users WHERE id = 6 FOR UPDATE;
  1. 事务 Aприобретенныйusersна столеэксклюзивная блокировка намерения.
  2. 事务 AПолучить данные в строке с идентификатором 6эксклюзивный замок.

после事务 Bхочу получитьusersТаблицаобщий замок:

LOCK TABLES users READ;
  1. 事务 Bобнаружен事务 AдержатьusersТаблицаэксклюзивная блокировка намерения.
  2. 事务 BправильноusersЗапрос на блокировку таблицы заблокирован (исключен).

Наконец事务 Cтоже хочу получитьusersстрока в таблицеэксклюзивный замок:

SELECT * FROM users WHERE id = 5 FOR UPDATE;
  1. 事务 CПрименятьusersТаблицаэксклюзивная блокировка намерения.
  2. 事务 Cобнаружен事务 AдержатьusersТаблицаэксклюзивная блокировка намерения.
  3. Поскольку блокировки намерения не являются взаимоисключающими, поэтому事务 CпонятноusersТаблицаэксклюзивная блокировка намерения.
  4. потому что нет строки данных с идентификатором 5эксклюзивный замок, наконец-то事务 CУспешно получены данные на линии данныхэксклюзивный замок.

Суммировать

  1. Поддержка InnoDB多粒度锁, в некоторых сценариях блокировки на уровне строки могут сосуществовать с блокировками на уровне таблицы.
  2. Блокировки намерения не исключают друг друга, но в дополнение к совместимости IS и S,意向锁会与 共享锁 / 排他锁 互斥.
  3. IX и IS являются блокировками на уровне таблицы и не будут конфликтовать с блокировками X и S на уровне строк. Он будет конфликтовать только с X и S на уровне таблицы.
  4. Для обеспечения параллелизма реализованы блокировки намерений.行锁和表锁共存и满足事务隔离性требования.

Использованная литература:

Дальнейшее чтение: