为什么在 SELECT 不插入时将 INSERT SELECT 插入不相关的表块?mysql 5.6

Kem*_*son 5 mysql innodb locking mysql-5.6

简而言之,我有一个表“app”,它有一个主要的自动增量字段 app_id,一个字段 created_at datetime 不为空。

我有另一个表“app_subset”,只有一个键“app_id”。

如果我运行这样的查询:

SELECT app_id FROM app;
Run Code Online (Sandbox Code Playgroud)

然后在运行时,我执行:

INSERT INTO app (created_at) VALUES (NOW());
Run Code Online (Sandbox Code Playgroud)

插入立即执行,而不是等待选择完成。

但是,如果我运行这样的查询:

INSERT IGNORE INTO app_subset SELECT app_id FROM app;
Run Code Online (Sandbox Code Playgroud)

然后在应用程序中运行相同的插入:

INSERT INTO app (created_at) VALUES (NOW());
Run Code Online (Sandbox Code Playgroud)

现在 INSERT INTO 应用程序查询阻塞,等待 INSERT IGNORE 完成。

我试图理解为什么会这样。我知道我的选择结果将被 INSERT INTO 应用程序更改,但似乎如果原始 SELECT 没有阻塞,那么使用该选择结果的 INSERT 也不应该阻塞。我希望能够以某种方式进行设置,以便以某种方式出现这种情况,或者至少完全理解为什么会发生这种情况,以便我可以预测将来会出现类似的问题。

从下面罗兰多的回答中,听起来 READ UNCOMMITED 应该可以工作,实际上当我执行时:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Run Code Online (Sandbox Code Playgroud)

INSERT IGNORE .. SELECT 不再导致我的 INSERT INTO 应用程序阻塞。

我很好奇是否有办法将它作为一行来做(比如:)

INSERT IGNORE INTO app_subset SELECT app_id FROM app LOCK IN NONSHARING MODE;
Run Code Online (Sandbox Code Playgroud)

Rol*_*DBA 7

实际上,INSERT INTO .. SELECT确实锁定了SELECT

我之前写过这个