MySQL MyISAM如何在不锁定表的情况下执行读取?

时间:2013-05-09 03:04:01

标签: mysql sql myisam

我的问题是对this answer.的跟进。我想了解如何在不使用MyISAM引擎锁定表的情况下执行select语句。

如果你有InnoDB而不是MyISAM,答案陈述如下。 MyISAM引擎的等价物是什么?

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;

2 个答案:

答案 0 :(得分:11)

这是MyISAM表的默认行为。如果实际上想要锁定MyISAM表,则必须手动获取表级锁。自MyISAM does not support transactions以来,事务隔离级别START TRANSACTIONCOMMITROLLBACK对MyISAM表的行为没有影响。

有关内部锁定机制的更多信息

在执行SELECT语句之前隐含地获取READ锁,并释放它。请注意,几个并发的,同时的SELECT语句可能同时运行,因为多个会话可能在同一个表上持有READ锁。

相反,在执行INSERTUPDATEDELETE语句之前,会隐含获取WRITE锁定。这意味着只要正在进行写入 * ,就不会发生读取(更不用说并发写入)。

以上内容仅适用于MyISAM,MEMORY和MERGE表。

您可能希望在此处详细了解:


* 但是,由于this clever trick,并不总是需要这些锁:

  

MyISAM存储引擎支持并发插入以减少给定表的读取器和写入器之间的争用:如果MyISAM表在数据文件的中间没有空闲块,则始终插入行在数据文件的末尾。在这种情况下,您可以自由地混合INSERT表的并发SELECTMyISAM语句,而不需要锁定。

答案 1 :(得分:5)

MyISAM确实在SELECT期间使用了读锁定。 一端的INSERT可以解决这个问题。

但是在长时间运行的UPDATE正在进行中时,请尝试执行DELETEALTER TABLESELECT。反之亦然,在对该表的更改运行时从表中读取。它是先到先得的,后来的线程阻塞直到第一个线程完成。

MyISAM对交易没有任何支持,因此它必须以这种方式工作。如果SELECT正在从表中读取行,并且并发线程会更改其中一些行,则会出现竞争条件。 SELECT可能会在更改之前读取一些行,并在更改之后读取一些行,从而导致数据的完全混合视图。

使用SET TRANSACTION ISOLATION LEVEL执行的任何操作都不会对MyISAM产生影响。

由于这些原因,建议改用InnoDB。