Php 如何解决InnoDB引擎中的死锁问题?

Php 如何解决InnoDB引擎中的死锁问题?,php,mysql,innodb,deadlock,Php,Mysql,Innodb,Deadlock,我听说过这个问题,现在我正在寻找更具体的信息 它是如何发生的,原因是什么,详细解释死锁的机制,试图避免它。如何检测死锁、解决死锁并保护数据不因死锁而损坏。这种情况是在PHP中使用MySQL时发生的 我可以混合使用InnoDB和MyISAM吗?我打算将innoDB用于一些有很多关系但没有那么多数据的主要文件,如用户、角色、特权、公司等,并将MyISAM用于包含更多数据的表:客户数据、操作数据等。我只想使用innoDB,但从MyISAM的移动在速度和稳定性方面让我有点害怕。现在这个死锁:(如果有两个

我听说过这个问题,现在我正在寻找更具体的信息

它是如何发生的,原因是什么,详细解释死锁的机制,试图避免它。如何检测死锁、解决死锁并保护数据不因死锁而损坏。这种情况是在PHP中使用MySQL时发生的


我可以混合使用InnoDB和MyISAM吗?我打算将innoDB用于一些有很多关系但没有那么多数据的主要文件,如用户、角色、特权、公司等,并将MyISAM用于包含更多数据的表:客户数据、操作数据等。我只想使用innoDB,但从MyISAM的移动在速度和稳定性方面让我有点害怕。现在这个死锁:(

如果有两个或多个独立的查询同时访问相同的资源(表/行),可能会发生死锁。一个真实的例子:

两名技工正在修理两辆车。在修理过程中的某个时候,他们都需要一把螺丝刀和一把锤子来松开一些严重卡住的零件。技工a抓住螺丝刀,技工B抓住锤子,现在两人都不能继续工作了,因为他们需要的第二个工具不可用:他们已经死锁了

现在,人类是聪明的,其中一个机制将很友好并将他们的工具交给另一个:两者都可以继续工作。数据库有点愚蠢,两个查询都不会友好并解锁导致死锁的任何资源。此时,DBMS将打开Rambo并强制回滚(或者干脆杀死)一个或多个相互锁定的查询。这将使一个幸运的查询继续并继续获得它所需的锁/事务,希望被中止的查询有足够智能的应用程序处理它们,稍后将重新启动事务。在旧的/更简单的DBMS上,整个系统将陷入停顿,直到DBA进入并重新启动做了一些手工清理

有很多方法可以处理死锁,并从一开始就避免死锁。其中一个重要的方法是永远不要将资源锁定在“随机”状态命令。在我们的机修工的情况下,两个人都应该先拿螺丝刀,然后再拿锤子。这样一来,一个人可以立即成功地工作,而另一个人则知道他必须等待

至于混合InnodB/MyISAM-MySQL完全支持在查询中混合/匹配表类型。您可以按任意顺序选择/join/update/insert/delete/alter,只需记住,在InnodB事务中对MyISAM表执行任何操作都不会使MyISAM神奇地感知事务。MyISAM部分将立即执行/提交,即如果您回滚InnoDB方面的内容,MyISAM也不会回滚


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

如果您不需要MyISAM特有的功能,如全文搜索或快速满表<代码>计数(*)s.MyISAM不比InnoDB快,InnoDB也不比MyISAM快。一种在一种情况下性能更好,另一种情况下性能更好。实际上,我切换到InnoDB是因为它在有很多写操作的表上性能更好,因为它使用行级锁定而不是MyISAM的表级锁定。因此,如果不需要任何MyISAM指定c特性,不要害怕切换;)关于死锁,这可能是我去InnoDB时的主要痛苦。我以前用过这个引擎,但从来没有在一个大的数据库。现在我正在开发一个应用程序,它使用了许多数据库(超过40个),每个数据库都是10-20MB。虽然没有那么多,但仍然有大量的数据。谢谢你,这是一个很好的答案,但是如何防止应用程序中的死锁呢?任何PHP示例都将非常有用。如果我简单地同时执行一些更新、插入、选择和删除,而不从脚本中实际锁定任何表,是否会出现死锁?我的意思是只是简单的查询,没有锁表之类的东西。还有一个问题。只有当两个事务同时访问同一行并且它们锁定了完成事务所需的资源时,才会发生死锁。我的意思是,我不明白一个简单的原子查询是如何导致死锁的。我说的对吗?如果没有锁,就不会有死锁。但是,如果两个查询都在同一行上工作,则这是一个竞争条件,最终可能会导致不一致的结果,具体取决于查询实际执行的顺序。不正确。如果发出insert、update或delete命令,InnoDB将自动锁定该行。From:“InnoDB使用自动行级锁定。即使在只插入或删除一行的事务中,您也可以获得死锁。这是因为这些操作不是真正的“原子”操作;它们会自动对插入或删除行的(可能是多个)索引记录设置锁。”