Mysql 执行select查询语句的时候 会自动加锁吗?

Mysql 执行 select 语句会根据表的引擎的不同而自动加锁吗?
或者说有没有什么文档是介绍Mysql 查询时内部的锁的机制(不是手动加锁)

更新一下问题,举例子:

myisam如果先在session1 中执行耗时长的select 查询(非事务),然后session2中执行update这个被查询的表的数据,会立即执行吗?还是要等到session1查询结束后才会执行?

做个实验

  1. select * from pre_common_member查询一下比较大的表
  2. update pre_common_member set password=1234568 where uid=4117593同时在另一个session 更新这个表
| 239 | root | localhost       | bbsdata    | Query   |   10 | Sending data                 | select * from pre_common_member                                                                      |
| 410 | root | localhost       | bbsdata    | Query   |    2 | Waiting for table level lock | update pre_common_member set password=1234568 where uid=4117593   

上面时两个语句执行中执行show processlist显示的结果,update 在等待table level locking

自己查了半天,找到的最贴近的文档内容:

MySQL grants table write locks as follows:

If there are no locks on the table, put a write lock on it.

Otherwise, put the lock request in the write lock queue.

MySQL grants table read locks as follows:

If there are no write locks on the table, put a read lock on it.

Otherwise, put the lock request in the read lock queue.
 

结论

因为select 是读取操作,所以会加read lock(我自己推理得出的,没有找到官方说法)。上面的实验中,update操作要等待select 的锁释放,才能加 write lock。 所以会卡住直到select 结束。而同时的select 操作则不需要等待,因为文档内说明了read lock的上锁条件为只要没有write lock 就可以。

决定放弃使用myisam表了,感觉mysql官方在5.5以上都已经设置Innodb为默认引擎了,我也没必要使用myisam了。

阅读 31.5k
5 个回答

InnoDB存储引擎实现了标准的行级锁,读锁和写锁(并行读串行写),还有表级锁,间隙锁。。。

查询时也会根据锁的粒度不同,效果也不同,具体看 链接描述

看高性能mysql去吧 新手老手都适合

InnoDB会根据事务隔离级别自动加锁,当然程序员可以手动加锁,但通常手动加锁不但没有必要还会影响性能;InnoDB的行级锁已经经过许多优化了。 ----来自高性能MySQL

新手上路,请多包涵

附議第三個回答,解鎖方式取決於事務的隔離等級。

新手上路,请多包涵

1,MySQL默认是Read-Repeatable隔离级别,Oracle、SQL Server等默认是Read Commited级别;

2,MySQL为什么默认是Read-Repeatable隔离级别?因为历史原因,早阶段Mysql(5.1版本之前)的Binlog类型Statement是默认格式,即依次记录系统接受的SQL请求;5.1及以后,MySQL提供了Row,Mixed,statement3种Binlog格式, 当binlog为statement格式,使用RC隔离级别时有bug;

3,什么情况下select读取会加读锁?
(1)在RC,RR下都不会隐形自动加锁,因为是使用的快照读;
(2)Serializable隔离级别下所有的读都会隐形自动加读锁,因为是当前读;亲测是这样的;

4,在RC,RR下对select如何加锁?
(1)select... lock in share mode,手动加读锁,
(2)select... for update,手动加写锁;

5,当前读、快照读、MVCC
(1)RC,RR使用的快照读;
(2)快照读,单纯的select操作,不会加锁;
(3)快照读的实现方式:undolog和多版本并发控制MVCC

(4)当前读:读取的是最新版本, 并且对读取的记录加锁, 阻塞其他事务同时改动相同记录,避免出现安全问题。
(5)当前读的实现方式:行记录锁+Gap间隙锁

推荐问题