我们正在创建一个应用程序,其中将有一个主服务器,但我们的客户端也将在办公室中有一台服务器,可能会失去与主服务器的连接。我们正在研究如何配置MySQL,以便1)通过互联网正常写入主设备,而奴隶只是被动地拉下来2)如果连接丢失了互联网/外部世界,读取和写入都是在办公室中有访问权限的本地服务器,以及3)连接恢复后,完成同步,完美无缺
一个小故障是这些从属服务器可能有2个或3个,因此同步必须足够强大,适用于多个服务器。
请注意,在网络连接断开之前,您有三台服务器,其联系人表包含100条记录。在最复杂的情况下,所有3个位置都会添加新记录。重新连接过程将识别未同步的记录,并且在完成该过程后,每个表将有103条记录,并且主键重新排序!
在外键上添加级联更新 - 关于在哪个方向上朝着正确方向前进的任何建议?我正在考虑为此编写PHP例程,但不想重新发明轮子。
谢谢!
答案 0 :(得分:0)
从根本上说,这将是一个非常难以设计,测试和维护的架构。我强烈建议您重新考虑您的设计是否需要分区容差(特别是允许写入未连接到主服务器的数据库的能力)。
如果这是绝对必要的,您需要处理的几个问题包括:
您需要完全停止使用AUTO_INCREMENT
主键,因为在拆分后几乎不可能安全地同步它们,因为多个服务器可能使用了相同的密钥,并且密钥可能存在于事后无法更新的位置(例如,在URL中!)。通过为每个服务器使用偏移量生成主键(例如,服务器A使用ID 100
,200
,300
,服务器B使用101
,201
,301
等,或使用GUID主键,以便永远不会发生冲突。
请注意,GUID主键对MySQL服务器性能有明显的负面影响,因为它们会使索引完全混乱。谨慎行事。
如果您认为同步更新数据库很困难,那么处理更新和删除操作会使比较简单。一种解决方法可能是完全避免更新和删除 - 将每个表视为“日志”,每次对象状态更改时(包括删除时)插入新行,并将最新行标识为“现状”。这将使您的数据库上的任何类型的关系操作基本上不可能(因为在这样的表上执行任何类型的有用JOIN非常困难!),但它至少会简化同步任务。
如果不可能,情况开始变得非常严峻。在网络未完全连接时,您可能最终需要维护所有更改的日志,并在每次服务器重新连接时协调这些日志。这可能不会很好地扩展。
请记住,任何自动冲突解决方案都可能导致一些数据丢失或意外结果。特别是,如果记录的单个字段由网络分割的两侧更新,则同步工具将需要选择其中一个新值以“获胜”,或以某种方式合并这些值。取决于场是什么以及它代表什么,这可能是非常困难的甚至是不可能的。 (对于一个特别糟糕的例子,考虑如果一个字段代表用户的银行帐户余额会发生什么,并且同步中的一方更新会丢失!)
如果您对这些主题感兴趣,您可能需要研究一些基础理论。特别感兴趣的几个概念将是:
TL; DR:分区容忍度很难。真的,真的很难。如果可能的话,尽量避免处理它。