2

我有一个单一的、未复制的 MySQL 服务器。

我们遇到了 INSERT INTO ... SELECT 语句导致源表上的写锁定的问题。

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

遵循此问题已接受答案的建议:如何改进 INSERT INTO ... SELECT 锁定行为

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

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

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

如何防止这种写锁?

4

2 回答 2

0

会有帮助吗?

如果您使用 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> 从 temp_table 中删除;

mysql>解锁表;

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

于 2013-04-12T17:32:14.260 回答
0

在我看来,您的事务隔离级别好像在对相同数据进行顺序读取时不允许插入。

明白这可能是件好事。MySQL 不会在这里无缘无故地阻塞。这只是意味着您的一条语句正在读取的数据在原子操作期间可能不会更改。因此,不授予 INSERT 插入数据的权限,否则会更改您现在插入到临时表中的数据。

您可以查看此页面,从 MySQL 的角度描述有关事务隔离的所有信息。

于 2013-04-12T17:25:42.067 回答