2010-10-18 108 views
1

我听说过这个问题,现在我正在寻找更具体的信息?如何解决InnoDB引擎中的死锁问题?

它是怎么发生的?原因是什么?详细解释死锁机制以尽量避免死锁。如何检测死锁,解决它并保护数据免于因此而被破坏。这种情况是在PHP中使用MySQL的情况。

我可以混合使用InnoDB和MyISAM吗?我打算使用innoDB来处理一些具有许多关系的数据库,而不是那些太多的数据,如用户,角色,权限,公司等,并且使用MyISAM来处理包含更多数据的表:客户数据,操作数据等。我希望只使用InnoDB,但从MyISAM的转变使我在速度和稳定性方面有点让人害怕。现在这个死锁:(如果你有两个或多个独立的查询在同一时间访问相同的资源(表/行)可能会发生

+0

如果您不需要MyISAM特定功能,如全文检索或快速全表COUNT(*),那么从MyISAM移动到InnoDB应该没有任何问题。 MyISAM不会比InnoDB更快,InnoDB也不会比MyISAM更快。一个表现更好,另一个表现更好。我实际上切换到了InnoDB,因为它在具有许多写操作的表上更具性能,因为它使用行级锁而不是MyISAM的表级锁。所以,如果你不需要任何MyISAM特有的功能,不要害怕切换;) – NikiC 2010-10-18 11:29:18

+0

那我怎么能在InnoDB中遇到这样的僵局呢?我之前使用过此引擎,但从未使用过大型数据库。现在我正在使用许多DB(超过40个)的应用程序工作,每个DB都是10-20MB。它并不多,但仍然有很多数据。 – 2010-10-18 11:48:30

回答

2

死锁一个真实世界的例子:

两个机械师正在在修理过程中的某一时刻,他们都需要一把螺丝刀和一把锤子来松开一些严重卡住的零件。机械师A抓起螺丝刀,机械师B抓起锤子,现在都不能继续,因为他们需要的第二种工具不可用:它们被锁定

现在,人类很聪明,其中一个机制会很亲切,并将他们的工具交给另一个:两者都可以继续工作。愚蠢的,并且这两个查询都不会很亲切,并且可以解开造成死锁的任何资源。此时,DBMS将转变Rambo并强制回滚(或仅仅杀死)一个或多个相互锁定的查询。这将让一个幸运查询继续并继续获取它所需的锁定/事务,并希望被中止的应用程序具有足够智能的应用程序来处理它们,这将稍后再次重新启动事务。在较旧/较简单的DBMS上,整个系统将停止运行,直到DBA进入并进行一些手动清理。

有很多方法可以应对死锁,并首先避免它们。一个重要的问题是永远不要将资源锁定在“随机”订单中。在我们的机械的情况下,在到达锤子之前,都应该首先到达螺丝刀。这样一个人可以立即成功工作,而另一个人会知道他必须等待。至于混合InnodB/MyISAM - MySQL完全支持在查询中混合/匹配表类型。你可以按你想要的顺序选择/ join/update/insert/delete/alter,只要记住在InnoDB事务中对MyISAM表进行任何操作都不会使MyISAM神奇地处理事务。 MyISAM部分将立即执行/提交,如果你回滚InnoDB这一方,MyISAM也不会回滚。

现在坚持使用MyISAM的唯一主要原因是它支持全文索引。除此之外,InnoDB通常会是更好的选择,因为它具有完整的事务支持和行级锁定。

+0

谢谢,这是一个很好的答案,但如何防止应用程序中的死锁?任何PHP示例都会很有用。如果我简单地执行一些更新,插入,选择和删除同时没有实际锁定脚本中的任何表,我会死锁吗?我的意思是简单的查询,没有像这样的东西。 – 2010-10-19 08:06:40

+0

还有一个问题。只有当两个事务同时访问同一行时,才会发生死锁,并且锁定了他们需要完成事务所需的资源。我的意思是我没有看到简单的原子查询如何导致死锁。我对吗? – 2010-10-19 08:15:24

+0

如果没有锁,那么就不会有死锁* LOCK *。但是,如果两个查询都在同一行上工作,那么这是一个竞争条件,并且最终可能会得到不一致的结果,具体取决于查询实际执行的顺序。 – 2010-10-19 12:11:00