Когда именно MySQL блокирует строку при обновлении таблицы InnoDB? - PullRequest
16 голосов
/ 29 июня 2011

Если у меня есть этот запрос на несколько обновлений

UPDATE user u
INNER JOIN user_profile up ON up.user_id = u.id
SET u.name = 'same_name_i_already_had', up.profile.age = 25
WHERE u.id = 10

Предположим, строка 10 в пользовательской таблице уже имеет имя same_name_i_already_had, поэтому ее не следует обновлять.

С другой стороны, строка в таблице user_profile имеет другой возраст, поэтому MySQL должен обновить ее.

Предполагая MySQL в качестве СУБД и InnoDB с его системой блокировки на уровне строк в качестве механизма обеих таблиц,

Блокирует ли MySQL строку в пользовательской таблице несмотря нет необходимости обновлять поле имени в этой строке?

Ответы [ 2 ]

13 голосов
/ 29 июня 2011

Блокирует строку в user. Вы можете проверить это, используя отличный инструмент innotop .

  • Запустите innotop и нажмите клавишу «L», чтобы отобразить экран блокировки InnoDB.
  • Откройте другой сеанс, войдите в MySQL и НАЧАТЬ СДЕЛКУ.
  • Выполните ОБНОВЛЕНИЕ, которое вы показали, но пока не выполняйте COMMIT.
  • Просмотр блокировок на экране innotop.

Например, я создал таблицы user и user_profile на моей тестовой виртуальной машине под управлением MySQL 5.5 и выполнил шаги, перечисленные выше. Вот вывод:

[RO] Locks (? for help) localhost, 08:34.568, InnoDB 10s :-), 0.10 QPS, 2/0/0 con/run/cac thds, 5.5.

__________________________________________ InnoDB Locks __________________________________________
ID  Type    Waiting  Wait   Active  Mode  DB    Table         Index    Ins Intent  Special        
 2  TABLE         0  00:00   02:35  IX    test  user                            0                 
 2  RECORD        0  00:00   02:35  X     test  user          PRIMARY           0  rec but not gap
 2  TABLE         0  00:00   02:35  IX    test  user_profile                    0                 
 2  RECORD        0  00:00   02:35  X     test  user_profile  PRIMARY           0  rec but not gap
4 голосов
/ 29 июня 2011

Почти наверняка он блокирует ряд независимо. Я не знаю каких-либо простых полей, которые проверяются на предмет изменения. Легче и быстрее просто блокировать, писать и разблокировать. Если перед блокировкой была проверка, то есть условие гонки: то, чего блокировка полностью избегает.

...