Unable to remove shard mapping using Azure SQL elastic scale

We have an entity in our system called an "identification program." This is also our boundary, each identification program is stored in its own fragment, so the fragment identifier is the identification program identifier.

We are in the process of realizing the possibility of physically removing the identification program. As part of this process, we want to clear the fragment map. For this, I wrote the following:

var shardKey = new Guid("E03F1DC0-5CA9-45AE-B6EC-0C90529C0062"); var connectionString = @"shard-catalog-connection-string"; var shardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(connectionString, ShardMapManagerLoadPolicy.Lazy); var shardMap = shardMapManager.GetListShardMap<Guid>("IdentityProgramIdListShardMap"); if (shardMap.TryGetMappingForKey(shardKey, out PointMapping<Guid> mapping)) { if (mapping.Status == MappingStatus.Online) { shardMap.MarkMappingOffline(mapping); } shardMap.DeleteMapping(mapping); } 

The problem is that when it gets into the DeleteMapping call, it gets an exception:

ShardManagementException: shard binding mapping '[shard-connection-string]' in the 'IdentityProgramIdListShardMap' shard map does not exist. An error occurred while executing the stored procedure "__ShardManagement.spBulkOperationShardMappingsGlobalBegin" for the operation "RemovePointMapping". This can happen if another simultaneous user has already deleted the display.

But the mapping was not removed, because right after that I do:

 mappings = shardMap.GetMappings(); foreach(var mapping in mappings) { Console.WriteLine(mapping.Value); } 

And I see that the shardmap entry still exists and is marked as "Offline".

If I delete the MarkMappingOffline call, I get an exception indicating that the display of the fragments cannot be removed because it is online.

So, I seem to have caught 22. If I tag it offline, he believes that the display of the fragments has disappeared and will not allow me to delete it. If I do not mark it as offline, it tells me that it should be offline.

+5
source share
1 answer

You should always work with the current version of the display, so the code should be

 if (shardMap.TryGetMappingForKey(shardKey, out PointMapping<Guid> mapping)) { if (mapping.Status == MappingStatus.Online) { // `mapping =` on next line is needed mapping = shardMap.MarkMappingOffline(mapping); } shardMap.DeleteMapping(mapping); } 

To clarify a bit: agile db tools use an optimistic concurrency model, where each operation verifies that you are working with the latest version of each object. The error message says that there was a "parallel" modification when matching, that is, someone else did MarkMappingOffline at the same time after you got the mapping, but before you did DeleteMapping. In fact, the โ€œother personโ€ was himself, but since you did not remove the latest version of the mapping, the flexible db tools did not know that it was you. :)

+6
source

Source: https://habr.com/ru/post/1272677/


All Articles