我编写了一些sql查询来进行etl处理,其中大量使用insert into。。。选择类型查询。我经常看到mysql复制由于锁定问题而停止。我尝试设置几乎所有可能的事务隔离级别(readuncommitted、committed),但似乎没有一个可以阻止工作。有哪些方法可以避免此锁定问题?
8hhllhi21#
innodb公司:
SET autocommit=0; LOCK TABLES t1 WRITE, t2 READ; ... do something with tables t1 and t2 here ... COMMIT; UNLOCK TABLES;
密萨姆:
LOCK TABLES t1 WRITE, t2 READ; ... do something with tables t1 and t2 here ... UNLOCK TABLES;
pqwbnv8z2#
如果您的问题不是您的查询在主服务器上死锁,而只是一个复制问题,那么您可以使用基于行的复制。由于只将结果数据修改传输到从属系统而不是查询,因此不应遇到锁定问题。
0vvn1miw3#
@mkp,当复制因“与锁相关的问题”而停止时,您能否明确指出错误消息是什么?源表的读取超时,因为该语句设置了写锁?我不是像@bill karwin建议的那样跳转到应用程序并返回到数据层,而是建议一个两步方案,第一步是创建一个临时表(如果可能的话,也可以在内存中),通过创建它并用相同的语句填充它,然后第二步是从tmp表复制到最终的表。
qvtsj1bj4#
当您执行读写混合语句时,mysql总是对您读取的行设置一个共享锁。
INSERT INTO <table> SELECT ... CREATE TABLE <table> AS SELECT ... SET @variable = (SELECT ...)
唯一的解决方法是分两步进行操作:使用只读select语句将行提取到客户端应用程序在随后的单独insert语句中使用提取的数据另请参见https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html
4条答案
按热度按时间8hhllhi21#
innodb公司:
密萨姆:
pqwbnv8z2#
如果您的问题不是您的查询在主服务器上死锁,而只是一个复制问题,那么您可以使用基于行的复制。由于只将结果数据修改传输到从属系统而不是查询,因此不应遇到锁定问题。
0vvn1miw3#
@mkp,当复制因“与锁相关的问题”而停止时,您能否明确指出错误消息是什么?源表的读取超时,因为该语句设置了写锁?
我不是像@bill karwin建议的那样跳转到应用程序并返回到数据层,而是建议一个两步方案,第一步是创建一个临时表(如果可能的话,也可以在内存中),通过创建它并用相同的语句填充它,然后第二步是从tmp表复制到最终的表。
qvtsj1bj4#
当您执行读写混合语句时,mysql总是对您读取的行设置一个共享锁。
唯一的解决方法是分两步进行操作:
使用只读select语句将行提取到客户端应用程序
在随后的单独insert语句中使用提取的数据
另请参见https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html