如何阻止一个节点上的死锁使整个集群崩溃?

Posted

技术标签:

【中文标题】如何阻止一个节点上的死锁使整个集群崩溃?【英文标题】:How to stop a deadlock on one node from crashing entire cluster? 【发布时间】:2017-11-23 08:30:43 【问题描述】:

我在 MariaDB 下运行一个 3x 节点 Galera 集群。该应用程序在 php 中使用 mysqli 扩展。

我偶尔会收到Deadlock 的写信。我正在努力改进我的应用程序以处理或避免这种故障,但同时我需要集群在发生这种情况时保持正常运行。

问题是一旦发生死锁,集群中的不仅仅是一个节点,而是所有三个节点都崩溃了。发生死锁的节点出现MySQL server has gone away 错误,在max_connect_errors 开始永久拒绝连接后,需要手动重启服务器。

我不明白为什么其他节点也会关闭。它们都以“WSREP 尚未准备好节点供应用程序使用”开始错误,这意味着整个应用程序崩溃,没有数据库节点接受连接。

当一个节点遭遇罕见的死锁时,如何确保集群的其余部分保持正常运行?


更新:

一个月后,另一个死锁导致了类似的问题。再一次,一个节点会破坏一切。

第一个连接出现死锁(在提交阶段),因此应用程序尝试重播事务。这挂了将近一分钟,然后再次失败。

在第一个连接恢复失败后,所有其他连接开始失败,并出现 (1205) "Lock wait timeout exceeded" 导致整个集群无用。

我应该补充一点,应用程序不使用锁。然而,它本身就是一个结,它只是与常规事务查询有关。

【问题讨论】:

深入了解所谓的“崩溃”。这听起来更像是挂起或错误配置的超时。让我们看看你的 my.cnf。不要不要使用'root' mysql 用户运行您的应用程序;然后会有一个备用连接供你进入。当你进入时,做SHOW PROCESSLIST;和其他诊断。 更新了类似的崩溃。 my.cnf 在这里:pastebin.com/raw/1e2bcrks 出于兴趣,您是否只在 MariaDB 上体验过这种体验,而不是原生 MySQL?因为他们在某种程度上可以互换的想法似乎并不正确。我们经历过 MariaDB 从相同的查询和数据集向 MySQL 产生不同的结果,以及两者之间的各种其他不一致。当然这是一个完全不同的问题,但我很想知道这是否是 MariaDB 特有的。 我在实施 Galera 集群的同时过渡到 MariaDB。即我从来没有集群原生 MySQL 我遇到了与@Tim 描述的完全相同的问题。你解决了吗? 【参考方案1】:

我正在回答我自己的问题,因为我已设法避免崩溃。但是,我仍然遇到次要错误的问题,并已开始 a new thread 详细说明。

我的恢复代码现在以不同方式处理次要错误。它将重试死锁几次,但仅限于错误是死锁时。如果发生任何其他类型的错误,应用程序将放弃。

虽然这意味着收到错误的用户很失望,但自此更改以来,我还没有发生过集群崩溃,也没有看到可怕的“服务器消失”错误。

【讨论】:

以上是关于如何阻止一个节点上的死锁使整个集群崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止节点 js 服务器崩溃

当 XNA windows 游戏关闭时,如何阻止 SoundEffect 使它们崩溃?

处理或防止错误使我在 Heroku 上的整个 node.js 应用程序崩溃

如何确保操作不会使整个应用程序崩溃?

快速失败Cassandra NTR阻止了任务

如何在 Spark Streaming 中自动重启故障节点?