提问者:小点点

Azure弹性数据库合并GUI关键碎片


在Azure中,我们有四个碎片,我想移除其中两个,因为我们不再需要它们了。数据应该合并到其他两个碎片中。

我使用带有GUID的Listmap作为键来标识碎片(在我们的应用程序中,这是用户ID)。在教程中,我只找到了将碎片与范围类型合并的示例。有没有一种方法可以更快地合并这些类型的碎片,或者我必须为此编写自己的工具?

如果合并是自动执行的,例如在以下情况下会发生什么:标识分片的GUID是用户ID,现在该数据从分片A移动到分片B。还有一个名为Comments的表,该表的用户ID为ForeignKey。此表中的PrimaryKey是一个经典的数字自动递增值。如果将这些值从碎片A移动到碎片B,会发生什么情况?它们是否会被插入并分配一个新的ID,或者根本不起作用?

此外,还有一些本地文件存储,它在路径中使用ID,因此无论如何我都必须编写自己的工具。

为此,我看了一下ShardMapManager,但并不完全理解它是如何工作的。在ShardMappingsGlobal表中有一个名为MappingId的列。但这不是存储在碎片数据库中的Guid/UserId。如何获得用于识别碎片的实际Guid,在我的情况下是UserId?我也没有找到在碎片之间移动数据的方法。我现在要做的是用自己的工具在碎片之间传输数据,然后使用ListShardMap。更新映射方法,为该值设置一个新的碎片。在操作结束时,我会使用ListShardMap。DeleteShard还是有更好的方法来做到这一点?

编辑:

我写了我自己的工具来合并碎片,但我现在得到了一个奇怪的异常。

        Guid userKey = Guid.Parse(userId);
        ListShardMap<Guid> map = GetUserShardMap<Guid>();

        try
        {
            PointMapping<Guid> currentMapping = map.GetMappingForKey(userKey);

            PointMapping<Guid> mappingOffline = map.UpdateMapping(currentMapping, new PointMappingUpdate()
            {
                Status = MappingStatus.Offline
            });  
         }

更新映射导致以下异常:

存储错误:错误515,级别16,状态2,过程__ShardManagement.spBulkoperationShardMappings本地,第98行,消息:无法将值NULL插入到列'LockOwnerId',表__ShardManagement。分片映射

我不明白为什么还有插入?我在本地和全局Shard映射表中检查了mappingId,映射是存在的,所以在我看来不需要插入。我还看了一下上面提到的存储过程的代码spBulkoperationShardMappings本地:https://github.com/Azure/elastic-db-tools/blob/master/Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerLocalFrom1.1To1.2.sql在插入语句中,LockOwnerId不会作为参数传递,因此只能失败。目前我的工作与一个测试设置,因为我不想发挥生产系统当然。也许我在那里犯了一个错误,但对我来说一切看起来都很好。


共1个答案

匿名用户

在教程中,我只找到了将碎片与范围类型合并的示例。有没有一种方法可以更快地合并这些类型的碎片,或者我必须为此编写自己的工具?

是的,拆分合并工具可以从范围和列表碎片贴图中移动数据。对于列表碎片映射,可以为每个键发出碎片移动请求。不幸的是,分割合并工具有一些复杂的设置,上次我花了大约一个小时来配置。我知道这不太好,我将让您决定是否需要更多或更少的时间来编写自己的自定义版本。

还有另一个名为注释的表,其UserId为ForeignKey。此表中的PrimaryKey是一个经典的数字自动增量值。如果这些值从碎片A移动到碎片B,会发生什么?它们会被插入并被分配一个新的ID给它们吗?还是这根本不起作用?

不会复制自动增量列的值,它们将在目标处重新生成。因此,将为这些行分配新的ID。

为此,我看了一下ShardMapManager,但并不完全理解它是如何工作的。在ShardMappingsGlobal表中有一个名为MappingId的列。但这不是存储在碎片数据库中的Guid/UserId。如何获得用于识别碎片的实际Guid,在我的情况下是UserId?

我强烈建议不要试图自己编辑ShardMapManager表,这很容易搞糟。编辑ShardMapManager表正是弹性数据库工具库的设计目的。

您可以使用ListShardMap更新映射的元数据。UpdatePointMapping方法。需要明确的是,这只会更新ShardMapManager表关于键的数据应该在哪里的知识。实际上,移动贴图必须由更高的层完成。

这是拆分合并服务的高级摘要:

  1. 锁定映射以防止来自另一个分片映射管理操作的并发更新
  2. 使用ListShardMap标记脱机映射。更新点映射。这将防止使用OpenConnectionForKey的数据定向路由被允许使用该密钥访问数据。它还会杀死分片上的所有当前会话,以迫使它们重新连接,这将确保没有使用现在离线键对数据进行操作的活动连接
  3. 移动基础数据,使用Shard Map的SchemaInfo来确定需要移动哪些表
  4. 更新映射并用ListShardMap在线标记它。更新点映射
  5. 解锁映射