2010-11-12 58 views
0

我有一个查询,我每天运行一次,从我的数据库中取出某些表并将它们放到一个表中,以便我可以快速导出我需要的任何格式的信息。有没有办法在MySQL中没有锁定?

我遇到然而一个问题,使我有以下错误:“SQLSTATE [40001]:序列化失败:1213死锁发现试图获取锁时,请尝试重新启动交易”

从我知道这听起来就像我的查询试图在已经存在锁定的情况下获取表上的锁定。然而我承认,我不知道任何关于表锁定或它是如何工作的。

真的,我只是想读其他表,而不写给他们,有没有办法,我可以创建查询,但不要求锁?

我的查询很可笑,所以这就是为什么我没有发布它。如果有某些部分需要告诉我,我可以发布。

+0

表的类型? InnoDB或MyISAM? – razzed 2010-11-12 16:13:44

+0

这些表都是InnoDB。 – 2010-11-12 16:22:47

回答

2

你可以尝试使用INSERT DELAYED,这里是做什么的:

When a client uses INSERT DELAYED, it gets an okay from the server at once, and the row is queued to be inserted when the table is not in use by any other thread.

如果你愿意看到在混合状态下的数据,您可以更改事务隔离级别

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
-- Problematic SELECT query goes here -- 
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; 

我了解到另一个SO的答案by Jon Erickson

+0

这不适用于InnoDB表,因为它们不支持INSERT DELAYED。 – 2011-09-11 16:38:15

2

如果您处于事务隔离模式REPEATABLE_READ(这是默认值),则选择应该不创建任何锁。这个是正常的。

但是,如果你使用插入...当然选择你会在目标表中锁定。

因此,如果没有其他人正在写入目标表,并且一次运行程序的最多只有一个副本,则永远不会发生死锁。

当两个(或更多)进程尝试执行永远不会完成的冲突事件时,会发生死锁。通常这涉及以不同顺序更新同一对行,但它可能取决于您的表结构。

思路来考虑:

  • 使用外置锁(InnoDB的),以
  • 更改事务隔离模式连载过程中对多个副本READ_COMMITTED此操作 - 如果你明白这是什么意思,并能容忍它。
  • 在一个事务(提交更加频繁)

你可以看到参与死锁的交易是干什么的,用SHOW ENGINE INNODB STATUS,僵局后少做工作。

你应该能够看到其他过程是什么以及他们在做什么。考虑打开一般日志或使用其他调试技术。

一定要在非生产系统中进行任何测试!