如何避免在插入时锁定。选择

时间:2018-11-19 23:46:03

标签: mysql locking

我编写了一些SQL查询来进行ETL处理,该查询大量使用INSERT INTO ... SELECT类型查询。我看到Mysql复制由于锁定问题而频繁停止。我尝试设置几乎所有可能的事务隔离级别(读未提交,已提交),但是似乎没有一个阻止它工作。有什么可能的方法来避免此锁定问题?

4 个答案:

答案 0 :(得分:0)

当您执行同时读取和写入的“混合”语句时,MySQL始终在读取的行上设置共享锁。

INSERT INTO <table> SELECT ...
CREATE TABLE <table> AS SELECT ...
SET @variable = (SELECT ...)

唯一的解决方法是分两个步骤进行操作:

  1. 使用只读SELECT语句将行提取到客户端应用程序
  2. 在随后的单独INSERT语句中使用获取的数据

另请参阅https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

答案 1 :(得分:0)

InnoDB:

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ;
... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;

MyISAM:

LOCK TABLES t1 WRITE, t2 READ;
... do something with tables t1 and t2 here ...
UNLOCK TABLES;

答案 2 :(得分:0)

@Mkp,您能否明确说明由于“与锁相关的问题”而停止复制时的错误消息是什么?源表的读取超时,是因为该语句设置了写锁定?

我仍然建议采用两步方案,而不是像@Bill Karwin那样跳回应用程序并返回到数据层,第一步是创建一个临时表(如果可能,也可能在内存中),通过创建它并将其填充到同一条语句中,然后,步骤2,就是从该tmp表复制到最终表。

答案 3 :(得分:0)

如果您的问题不是在MASTER上陷入僵局的查询,而仅仅是复制问题,则可以使用Row-Based replication。由于仅将产生的数据修改传输到从属设备而不是查询中,因此您不应遇到锁定问题。