Mongodb 如何使用Mongo DB处理应用程序死亡和其他中间操作故障

Mongodb 如何使用Mongo DB处理应用程序死亡和其他中间操作故障,mongodb,corruption,Mongodb,Corruption,由于Mongo没有事务可用于确保数据库没有提交任何内容,除非其数据一致(未损坏),如果我的应用程序在写入一个文档和相关写入另一个文档之间死亡,我可以使用什么技术来删除损坏的数据和/或以某种方式进行恢复?NoSQL背后更伟大的想法是针对特定问题使用精心建模的数据结构,而不是用锤子敲打每个问题。对于事务来说也是如此,它应该被称为“短命事务”,因为典型的RDBMS事务对“真实的”长命事务几乎没有帮助 RDBMS支持的事务类型通常是必需的,因为有限的数据模型迫使您跨多个表存储数据,而不是使用嵌入式数组(

由于Mongo没有事务可用于确保数据库没有提交任何内容,除非其数据一致(未损坏),如果我的应用程序在写入一个文档和相关写入另一个文档之间死亡,我可以使用什么技术来删除损坏的数据和/或以某种方式进行恢复?

NoSQL背后更伟大的想法是针对特定问题使用精心建模的数据结构,而不是用锤子敲打每个问题。对于事务来说也是如此,它应该被称为“短命事务”,因为典型的RDBMS事务对“真实的”长命事务几乎没有帮助

RDBMS支持的事务类型通常是必需的,因为有限的数据模型迫使您跨多个表存储数据,而不是使用嵌入式数组(想想典型的发票/发票项示例)

在MongoDB中,尝试使用写重、非规范化的数据结构,并将数据保存在单个文档中,这样可以提高读取速度、数据局部性并确保一致性。这样的数据模型也更易于扩展,因为单个只读访问单个服务器,而不必从多个源收集数据


然而,在某些情况下,数据必须在各种上下文中读取,并且去规范化变得不可行。在这种情况下,您可能希望查看或选择一种完全不同的并发方法,例如(在一句话中,svn、git等都是这样做的)。然而,后者很难取代RDBMs,但如果不是用户的话,它会向更高级别的应用程序(如果不是用户的话)暴露出一种完全不同的并发性。

考虑到这一点,我想确定一些类型的影响:

  • 您的操作只有一个数据库保存(将数据保存到一个文档中)
  • 您的操作有两个数据库保存(更新、插入或删除),A和B
  • 他们是独立的
  • B是A有效的必要条件
  • 它们是相互依赖的(A要求B有效,B要求A有效)
  • 您的操作有两个以上的数据库保存
  • 我认为这是一个全面的可能性清单。在案例1中,您没有问题-一个数据库保存是原子的。在案例2.1中,同样的事情,如果它们是独立的,那么它们也可能是两个独立的操作

    对于案例2.2,如果先执行A,然后执行B,最坏情况下,您将拥有一些额外的数据(B数据),这些数据将占用系统中的空间,但在其他方面是无害的。在案例2.3中,如果发生灾难性故障,您可能会有一些损坏的数据。案例3只是案例2的组成部分

    不同情况下的一些示例:

    1.0。将汽车文档的颜色更改为“蓝色”

    2.1。将汽车文档的颜色更改为“红色”,将驾驶员的头发颜色更改为“红色”

    2.2。创建一个新的引擎文档并将其ID添加到car文档中

    2.3.a。您将汽车的“gasType”改为“diesel”,这需要将发动机改为“diesel”型发动机

    2.3.b。2.3的另一个示例:将汽车文档A挂接到另一个汽车文档B,A将“TowerBy”属性设置为B的ID,B将“Towering”属性设置为A的ID

    3.0。我将把这些例子留给你想象

    在许多情况下,可以将2.3场景转换为2.2场景。在2.3.a示例中,car文档和engine是单独的文档。在本例中,让我们忽略将发动机放入汽车文档中的可能性。柴油发动机和非柴油气体以及非柴油发动机和柴油气体都是无效的。所以他们都必须改变。但如果根本没有发动机,而是使用柴油,这可能是有效的。因此,您可以添加一个步骤,使整个过程在所有点上都有效。首先,拆下发动机,然后更换汽油,然后更换发动机类型,最后将发动机装回到车上

    如果您将从2.3场景中获取损坏的数据,则需要一种检测损坏的方法。在示例2.3.b中,如果一个文档具有“拖航”属性,而另一个文档没有相应的“拖航”属性,则可能会出现问题。因此,这可能是灾难性故障后需要检查的内容。查找所有具有“拖航”属性的文档,但该属性中id为的文档未将其“拖航”设置为正确的id。可以选择删除“拖航”属性或设置相应的“拖航”属性。它们似乎都同样有效,但这可能取决于您的应用程序

    在某些情况下,您可能会发现这样的损坏数据,但在设置这些数据之前,您不知道这些数据是什么。在这些情况下,设置默认值可能比不设置要好。某些类型的损坏比其他类型的损坏要好(特别是会导致应用程序出错而不仅仅是显示数据不正确的损坏)


    如果上述类型的代码分析或损坏修复变得不可行,或者如果您想避免任何数据损坏,您的最后手段将是采纳mnemosyn的建议并实施,或者类似的东西,允许您在不确定状态下识别和回滚更改。

    原子数据应始终写入一个文档中。虽然这并不总是可能的(这很可能表明MongoDB是错误的DBMS),但适当的数据建模通常提供了一个解决方案。请描述您的用例并向我们展示您的数据模型–通常可以找到解决方案。我感谢您提供的帮助,但我正在寻找更通用的技术。如果你能用两个不同的例子写出一个答案,每个例子都展示了一种不同的“适当的数据建模”技术,那就太好了(也许还有一个例子展示了Mongo将在哪里进行建模)