当MySQL在更新InnoDB表时确切地锁定了一行?

Emi*_*lás 16 mysql innodb locking rowlocking

如果我有这个multiupdate查询

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
Run Code Online (Sandbox Code Playgroud)

假设用户表中的第10行已经具有名称"same_name_i_already_had",因此不应该更新它.

另一方面,user_profile表中的行具有不同的年龄,因此MySQL应该更新它.

假设MySQL作为RDBMS和InnoDB,其行级锁定系统作为两个表的引擎,

MySQL是否会锁定用户表中的行,尽管不必更新该行的名称字段?

Bil*_*win 13

它确实锁定了行user.您可以使用优秀的innotop工具验证这一点.

  • 运行innotop并按"L"键以显示InnoDB锁定屏幕.
  • 打开另一个会话,登录MySQL并启动TRANSACTION.
  • 执行您显示的UPDATE,但不要COMMIT.
  • 在innotop屏幕中查看锁定.

例如,我在运行MySQL 5.5的测试VM上创建了表user和user_profile,我执行了上面列出的步骤.这是输出:

[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
Run Code Online (Sandbox Code Playgroud)

  • "IX"模式是表级锁,意思是"我*打算*锁定此表中的某些行".它不会阻止同一个表上的行级锁,但它会阻止表级锁.有关InnoDB锁定的完整说明,请参阅http://dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.html,以及http://innotop.googlecode.com/svn/html/manual .html有关使用innotop的完整说明. (2认同)