栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

SELECT…ORDER BY XXX LIMIT 1 FOR UPDATE将锁定多少行?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SELECT…ORDER BY XXX LIMIT 1 FOR UPDATE将锁定多少行?

这是一个很好的问题。InnoDB是行级锁定引擎,但必须设置其他锁定以确保二进制日志(用于复制;时间点恢复)的安全性。要开始对其进行解释,请考虑以下(朴素的)示例:

session1> START TRANSACTION;session1> DELETe FROM users WHERe is_deleted = 1; # 1 row matches (user_id 10), deleted.session2> START TRANSACTION;session2> UPDATE users SET is_deleted = 1 WHERe user_id = 5; # 1 row matches.session2> COMMIT;session1> COMMIT;

由于语句仅在提交后才写入二进制日志,因此将在从属会话#2上首先应用该语句,并将产生不同的结果, 从而导致数据损坏

因此,InnoDB要做的是设置其他锁。如果

is_deleted
已建立索引,那么在session1提交之前,其他任何人都无法修改 或将 记录
插入到 where的记录 范围
is_deleted=1
。如果上没有索引
is_deleted
,则InnoDB需要锁定整个表中的每一行,以确保重播顺序相同。您可以将其视为
锁定间隙这与直接从行级锁定掌握的概念不同


在这种情况下

ORDER BY position ASC
,InnoDB需要确保在最低键值和可能的“特殊”最低值之间不能修改任何新行。如果您做得
ORDERBY position DESC
很好,则没有人可以插入此范围。

解决方案如下:

  • 基于语句的二进制日志很烂。我真的很期待将来我们都切换到基于行的二进制日志记录(可从MySQL 5.1获得,但默认情况下未启用)。

  • 使用基于行的复制时,如果将隔离级别更改为“已提交读”,则仅需要锁定匹配的一行。

  • 如果要成为受虐狂,还可以使用基于语句的复制来打开innodb_locks_unsafe_for_binlog。


4月22日更新 :要复制并粘贴我改进的测试用例版本(它不是在空白中搜索):

session1> CREATE TABLE test (id int not null primary key auto_increment, data1 int, data2 int, INDEX(data1)) engine=innodb;Query OK, 0 rows affected (0.00 sec)session1> INSERT INTO test VALUES (NULL, 1, 2), (NULL, 2, 1), (5, 2, 2), (6, 3, 3), (3, 3, 4), (4, 4, 3);Query OK, 6 rows affected (0.00 sec)Records: 6  Duplicates: 0  Warnings: 0session1> start transaction;Query OK, 0 rows affected (0.00 sec)session1> SELECT id FROM test ORDER BY data1 LIMIT 1 FOR UPDATe;+----+| id |+----+|  1 |+----+1 row in set (0.00 sec)session2> INSERT INTO test values (NULL, 0, 99); # blocks - 0 is in the gap between the lowest value found (1) and the "special" lowest value.# At the same time, from information_schema:localhost information_schema> select * from innodb_locksG*************************** 1. row ***************************    lock_id: 151A1C:1735:4:2lock_trx_id: 151A1C  lock_mode: X,GAP  lock_type: RECORD lock_table: `so5694658`.`test` lock_index: `data1` lock_space: 1735  lock_page: 4   lock_rec: 2  lock_data: 1, 1*************************** 2. row ***************************    lock_id: 151A1A:1735:4:2lock_trx_id: 151A1A  lock_mode: X  lock_type: RECORD lock_table: `so5694658`.`test` lock_index: `data1` lock_space: 1735  lock_page: 4   lock_rec: 2  lock_data: 1, 12 rows in set (0.00 sec)# Another example:select * from test where id < 1 for update; # blocks


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/411690.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号