Percona XtraDB集群多节点写入和事务外的意外死锁



我在使用google或Stack Overflow找到这个问题的答案时遇到了困难,所以熟悉Percona XtraDB的人可能会帮助回答这个问题。我完全理解本文中概述的意外死锁是如何发生的,解决方案是确保使用重试逻辑包装事务,以便在事务失败时重新启动它们。我们已经这样做了。

https://www.percona.com/blog/2012/08/17/percona-xtradb-cluster-multi-node-writing-and-unexpected-deadlocks/

我的问题是关于在自动提交模式下发生在事务之外的正常更新。通常,如果您只向单个SQL数据库写入并执行更新,则会得到最后一个wins场景,因此无论谁最后执行该语句,都是黄金。任何其他数据都会丢失,因此如果同时发生两次更新,其中一次将占据主导地位,而其他数据基本上会丢失。

现在,在具有相同内容的多主机环境中会发生什么?集群模式与多主机模式的区别在于,死锁可能发生在提交发生的点,而不是第一次对表执行锁时。因此,在自动提交模式下,数据将被写入数据库,但当它试图将数据提交给集群中的其他节点时,如果其他人同时修改了完全相同的记录,它可能会失败。显然,简单的解决方案是再次重新执行更新,在我看来,数据库本身应该能够处理这一问题,因为它是自动提交模式下的单个语句?

那么,在这种情况下会发生这种情况吗?还是我需要开始在重试处理中包装所有更新代码,并在失败时自己重试?

自动提交仍然是一个事务;单对账单交易。您的单个语句仅包含在BEGIN/COMMIT中。我相信你的逻辑是颠倒的。在PXC中,规则是"提交优先获胜"。如果在node1(即:autocommit=0;BEGIN;)和UPDATE id=1上启动手动事务,但不提交,则在node2上自动提交对同一行的更新,这将在node2和node1上成功。当您提交手动UPDATE时,您将得到一个死锁错误。这是正确的行为。

是否自动提交并不重要;先提交的一方获胜,另一个事务必须重试。这就是为什么我们不建议在PXC中写入多个节点的原因。

是的,如果你想写入多个节点,你需要调整你的代码来"尝试捕获重试"处理这个错误案例。

相关内容

  • 没有找到相关文章

最新更新