MySQL 何时在更新 InnoDB 表时锁定一行?

发布于 2024-11-17 15:53:56 字数 437 浏览 2 评论 0原文

如果我有这个多重更新查询,

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作为RDBMS,InnoDB以其行级锁定系统作为两个表的引擎,

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

If I have this multiupdate query

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

Let's suppose the row 10 in user table already has the name 'same_name_i_already_had', so it shouldn't be updated.

On the other hand, the row in user_profile table has a different age, so MySQL should update it.

Assuming MySQL as RDBMS and InnoDB with its row level locking system as the engine of both tables,

Does MySQL lock the row in user table in spite of not having to update the name field of that row?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雄赳赳气昂昂 2024-11-24 15:53:56

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

  • 运行 innotop 并按“L”键显示 InnoDB 锁屏幕。
  • 打开另一个会话,登录 MySQL 并开始事务。
  • 执行您显示的更新,但尚未提交。
  • 在 innotop 屏幕中查看锁。

例如,我在运行 MySQL 5.5 的测试虚拟机上创建了表 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

It does lock the row in user. You can verify this using the excellent innotop tool.

  • Run innotop and press the 'L' key to display a screen of InnoDB locks.
  • Open another session, log into MySQL and START TRANSACTION.
  • Execute the UPDATE you showed, but do not COMMIT yet.
  • View the locks in the innotop screen.

For example, I created tables user and user_profile on my test VM running MySQL 5.5, and I performed the steps I list above. Here's the output:

[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
゛清羽墨安 2024-11-24 15:53:56

几乎可以肯定,无论如何它都会锁定该行。我不知道有什么简单的字段会首先检查更改。锁定、写入和解锁更加简单快捷。如果在锁定之前进行了检查,那么就会出现竞争条件:锁完全避免的情况。

Almost surely it locks the row regardless. I don't know of any simple fields which are checked for a change first. It is easier and faster to just lock, write, and unlock. If there were a check before locking, then there is a race condition: something which a lock completely avoids.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文