我想知道,当网络分区发生和恢复时,是否有关于实现CAP定理中最终一致性的AP的存储应该如何表现的建议策略或规则.AP意味着当副本 node 与主 node 断开连接时,DBMS允许客户端进行写入.但是,当网络恢复并运行时,副本服务器在副本服务器和领导者/主服务器之间的网络中断期间写入的数据会发生什么情况?

举个例子:

  1. Person地址恰好在两个引线中更新,并因数据冲突而与引线副本断开连接.副本的数据会被替换吗?
  2. 新添加到副本的记录/文档如何?当连接恢复时,它们是否会消失或同步回引线?

推荐答案

在MySQL中,数据更改事件被写入源实例上的日志(log).复制副本远程订阅此日志(log),因此在新事件提交到日志(log)后,它会非常迅速地下载新事件.一旦它下载了该部分日志(log),它就可以根据它自己的数据实例重播事件.

只要源实例不太快地清除日志(log),网络就可以中断,或者可以重新启动副本或其他任何东西,并且在重新连接时,它将从中断的位置恢复.当然,复制品必须跟踪其下载和重播这些事件的进度.

我一直在支持离线太久的副本数据库实例.例如,如果副本服务器中的某个硬件需要更换,并且需要几天时间才能发货,则当副本最终try 下载时,源上的日志(log)早已不复存在.

仅当以正确的顺序重播所有事件时,复制副本才具有完整性.如果由于日志(log)已过期而无法恢复,则复制副本将无法恢复.在这种情况下,我们通过删除复制副本的所有数据来重新初始化复制副本,从源获取整个数据集的新快照,然后从该点重新开始.我们不得不一周做几次,因为我们运行了数千个复制品.


请回复您的 comments :

您是手动重新初始化复制副本,还是可以自动完成整个过程(删除数据、恢复快照等)?

很难制定出一种在每个人的环境中都有效的解决方案.

在我的上一份工作中,我们开发了自己的自动化来完成这项工作,因此我们可以运行一个命令来启动后台重建请求.这与手动执行的步骤相同,但我们在自动化服务中运行的代码中实现了这些步骤.这样我们就不会忘记一个步骤,我们不依赖任何人的笔记本电脑或交互会话,自动化具有良好的质量保证,它可以进行重试,可以并行运行多个作业(job),可以报告进度.但该解决方案是为我们工作的环境量身定做的.我们必须遵守服务器命名约定、网络安全策略、监控和alert 系统等.

MySQL Clone plugin是最近的一项新技术,声称可以做类似的事情,但我还没有机会try 它.

MySQL在任何配置中都不允许写入副本,不是吗?

默认情况下,MySQL确实允许直接在副本上进行更改.当然,如果您不小心,这可能会损害副本的完整性.因此,在许多环境中,最好在副本服务器上设置配置选项read_only=ONsuper_read_only=ON以防止出现这种情况.


当连接恢复并且复制副本能够同步到源时,在与源断开连接时更新和插入的复制副本数据会发生什么情况?我想知道对复制副本的所有写入是否都将丢失

MySQL复制不执行完全重新同步.它无法确保副本与其源同步.复制仅重放增量更改事件.如果两个实例从相同的状态开始,并且所有更改都是确定性的,那么在理论上它们是should保持同步的,则这是可行的.

在实践中,存在"数据漂移"的非零风险--即副本的数据与其源上的数据存在差异.MySQL的复制解决方案无法检测数据漂移.有像pt-table-checksum这样的第三方工具试图做到这一点,但它们在检测差异方面并不是pt-table-checksum%完美的.

要将风险降至最低,请执行以下操作:

  • 在复制副本时,切勿将更改直接写入复制副本.
  • 如果发生网络分区,则依靠Quorum.您将需要奇数个实例,因此如果存在网络分区,则一个或另一个分区具有大多数实例,并且可以确定一个实例作为源.分区中没有仲裁的实例必须保持只读.
  • 使用基于行的复制而不是基于语句的复制.见https://dev.mysql.com/doc/refman/8.0/en/replication-sbr-rbr.html

Database相关问答推荐

Golang Gorm和Gin无法创建具有关联的对象

是否有一个简单的工具可以将 mysql 转换为 postgresql 语法?

哪个能够存储 1 亿条记录的嵌入式数据库具有高效的 C 或 C++ API

数据库模式 - location

MySQL 慢查询日志(log) - 慢有多慢?

从 DbDataReader 读取数据的最快方法是什么?

将整数作为字符串存储在数据库中的缺点

数据库设计:喜欢表?

matlab 数据文件到 pandas DataFrame

MySQL 中的多个 OR 子句

如何在 MSSQL 2005 中创建递归查询?

为什么 MySQL 连接被许多连接错误阻止?

如何使用 INSERT ... ON CONFLICT ... 更新所有列?

如何产生幻读?

如何从 T-SQL 中的表中 Select 前 N 行?

你如何记录你的数据库 struct ?

设计数据库来保存不同的元数据信息

Rake aborted... table ‘users’ already exists

将 NULL 插入 MySQL 时间戳

数据库 - (行或记录、列或字段)?