如何解决MySQL INSERT INTO ... SELECT导致SELECTed表的写锁定?

时间:2013-04-12 17:01:36

标签: mysql locking

我有一个没有复制的MySQL服务器。

我们遇到一个问题,INSERT INTO ... SELECT语句导致原始表上的写锁定。

原始表位于一个数据库中。目标表是另一个数据库中的临时表。

按照这个问题的建议接受的答案:How to improve INSERT INTO ... SELECT locking behavior

我在my.cnf中更改了以下三个配置变量并重新启动了服务器:

innodb_autoinc_lock_mode=2
binlog_format=row
transaction-isolation=READ-COMMITTED

这似乎使问题变得更糟,尽管在这种情况下相关性可能不是因果关系。

如何防止此写锁定?

2 个答案:

答案 0 :(得分:0)

听起来好像你的事务隔离级别不允许INSERTS,而正在进行相同数据的顺序读取。

明白这可能是一件好事。 MySQL不会在这里阻止任何事情。它只是意味着在一个语句中读取的数据在原子操作期间可能不会被更改。因此,INSERT没有被允许插入数据,否则这些数据会改变您现在插入临时表的数据。

您可以查看this page,从MySQL的角度描述有关事务隔离的所有内容。

答案 1 :(得分:0)

this会有帮助吗?

  

如果使用LOCK TABLES显式获取表锁,则可以请求READ LOCAL锁而不是READ锁,以使其他会话在锁定表时执行并发插入。

     

要在无法进行并发插入时对表real_table执行许多INSERT和SELECT操作,可以将行插入临时表temp_table,并定期使用临时表中的行更新实际表。这可以使用以下代码完成:

     

的MySQL> LOCK TABLES real_table WRITE,temp_table WRITE;

     

的MySQL> INSERT INTO real_table SELECT * FROM temp_table;

     

的MySQL> DELETE FROM temp_table;

     

的MySQL>解锁表格;

     

InnoDB使用行锁,BDB使用页锁。这些存储引擎可能存在死锁,因为它们会在处理SQL语句期间自动获取锁,而不是在事务开始时。