5

Chúng tôi có một thực thể trong hệ thống của chúng tôi được gọi là "chương trình nhận diện". Đó cũng là ranh giới sharding của chúng tôi, mọi chương trình nhận dạng được lưu trữ trong phân đoạn riêng của nó, vì vậy mã nhận dạng của phân đoạn là định danh của chương trình nhận diện.Không thể xóa ánh xạ phân đoạn sử dụng Azure SQL Elastic Scale

Chúng tôi đang trong quá trình triển khai khả năng xóa thực tế chương trình nhận dạng. Là một phần của quá trình đó, chúng tôi muốn dọn dẹp bản đồ phân đoạn. Để làm như vậy tôi đã viết như sau:

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); 
} 

Vấn đề là khi nó chạm vào DeleteMapping gọi nó được một ngoại lệ:

ShardManagementException: Lập bản đồ tham khảo mảnh '[mảnh kết nối dây ] 'trong bản đồ phân mảnh' IdentityProgramIdListShardMap 'không tồn tại. Đã xảy ra lỗi trong khi thực hiện thủ tục được lưu trữ '__ShardManagement.spBulkOperationShardMappingsGlobalBegin' cho thao tác 'RemovePointMapping'. Điều này có thể xảy ra nếu một người dùng đồng thời khác đã loại bỏ ánh xạ.

Nhưng các bản đồ chưa được loại bỏ, vì ngay sau đó tôi thực hiện:

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

Và tôi có thể thấy rằng sự xâm nhập shardmap vẫn còn đó, và được đánh dấu Offline.

Nếu tôi xóa cuộc gọi đến MarkMappingOffline Tôi nhận được ngoại lệ cho biết rằng không thể xóa ánh xạ phân đoạn vì nó đang trực tuyến.

Vì vậy, tôi dường như có điểm bắt sóng 22. Nếu tôi đánh dấu nó ngoại tuyến nó nghĩ rằng bản đồ phân đoạn đã biến mất và sẽ không cho phép tôi xóa nó. Nếu tôi không đánh dấu nó là ngoại tuyến, nó sẽ cho tôi biết nó phải ngoại tuyến.

Trả lời

6

Bạn luôn luôn phải hoạt động trên phiên bản hiện tại của bản đồ, vì vậy bạn mã nên được

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); 
} 

Để giải thích thêm một chút: đàn hồi cụ db sử dụng một mô hình đồng thời lạc quan trong đó mỗi kiểm tra hoạt động mà bạn hoạt động trên phiên bản mới nhất của từng đối tượng. Thông báo lỗi nói rằng có một sửa đổi "đồng thời" đối với ánh xạ, tức là ai đó đã đồng thời thực hiện MarkMappingOffline sau khi bạn có ánh xạ nhưng trước khi bạn thực hiện Xóa bản đồ. Thực tế là "người khác" là bản thân bạn, nhưng vì bạn không xóa phiên bản mới nhất của bản đồ, các công cụ db đàn hồi không nhận thức được rằng đó là bạn. :)

+0

Cảm ơn bạn đã giải thích. Tôi đã thực sự tìm ra điều này ngay sau khi tôi đăng câu hỏi đó là lý do tại sao tôi đã không nhận được trở lại với nó để đánh dấu câu trả lời. Tôi (nhầm lẫn) giả định rằng 'shardMap.MarkMappingOffline (ánh xạ);' chỉ đơn giản là sửa đổi 'ánh xạ' được truyền vào thay vì trả về một thể hiện mới/đã sửa đổi. Tất cả đều đang hoạt động. –

+0

Bất kỳ cách nào để làm điều này bằng cách sử dụng Powershell? – Deepak

Các vấn đề liên quan