简体   繁体   English

Microsoft.Azure.Cosmos.Table LocationMode.SecondaryOnly RA-GRS Exception 此操作只能针对主存储位置执行

[英]Microsoft.Azure.Cosmos.Table LocationMode.SecondaryOnly RA-GRS Exception This operation can only be executed against the primary storage location

I was having as tough time getting Microsoft.Azure.Cosmos.Table to automatically initialise the SecondaryUri when parsing a connection string that used a SAS token.在解析使用 SAS 令牌的连接字符串时,我很难让 Microsoft.Azure.Cosmos.Table 自动初始化 SecondaryUri。

So I ended up explicitly specifying the TableSecondaryEndpoint in the connection string, that works but I'm unable to query the secondary because the SDK throws an Exception before even attempting the request.所以我最终在连接字符串中明确指定了 TableSecondaryEndpoint,这有效,但我无法查询辅助,因为 SDK 在尝试请求之前抛出异常。

In my testing, I have identified that this is a regression not present in Microsoft.WindowsAzure.Storage.Table 8.7.0 (The basis for Microsoft.Azure.Cosmos.Table 1.0.6)在我的测试中,我发现这是 Microsoft.WindowsAzure.Storage.Table 8.7.0(Microsoft.Azure.Cosmos.Table 1.0.6 的基础)中不存在的回归

Expert opinions very welcome that this point.非常欢迎专家意见指出这一点。 Thank you.谢谢你。

Project code for this Exception here (also copied below): https://github.com/golfalot/SOshowAzureTableBug这里异常的项目代码(也在下面复制): https : //github.com/golfalot/SOshowAzureTableBug

Side issue detailing the SecondaryUri initialisation problem raised here: https://github.com/Azure/azure-cosmos-table-dotnet/issues/36详细说明此处提出的 SecondaryUri 初始化问题的附带问题: https : //github.com/Azure/azure-cosmos-table-dotnet/issues/36

using System;
using System.Collections.Generic;

using LEGACY_STORAGE = Microsoft.WindowsAzure.Storage;
using LEGACY_RETRY = Microsoft.WindowsAzure.Storage.RetryPolicies;
using LEGACY_TABLE = Microsoft.WindowsAzure.Storage.Table; //8.7.0 because this is the base for 1.0.6

using NEWEST_TABLE = Microsoft.Azure.Cosmos.Table; // version 1.0.6
using Microsoft.Azure.Cosmos.Table; // had to add this to get access CreateCloudTableClient extension method

using System.Diagnostics;

namespace SOshowAzureTableBug
{
    class Program
    {
        // the SAS token is immaterial in reproducing the problem
        const string connectionTableSAS = "TableSecondaryEndpoint=http://127.0.0.1:10002/devstoreaccount1-secondary;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;SharedAccessSignature=immaterial";
        static void Main(string[] args)
        {

            /* Legacy Table SDK */
            var storageAccountLegacy = LEGACY_STORAGE.CloudStorageAccount.Parse(connectionTableSAS);
            var tableClientLegacy = storageAccountLegacy.CreateCloudTableClient();
            Debug.Assert(tableClientLegacy.StorageUri.SecondaryUri != null); // demonstrate SecondaryUri initialised

            var tableRequestOptionsLegacy = new LEGACY_TABLE.TableRequestOptions () { LocationMode = LEGACY_RETRY.LocationMode.SecondaryOnly };
            tableClientLegacy.DefaultRequestOptions = tableRequestOptionsLegacy;

            var tableLegacy = tableClientLegacy.GetTableReference("foo"); // don't need table to exist to show the issue
            var retrieveOperation = LEGACY_TABLE.TableOperation.Retrieve(string.Empty, string.Empty, new List<string>() { "bar" });

            var tableResult = tableLegacy.Execute(retrieveOperation);
            Console.WriteLine("Legacy PASS");


            /* Newset Table SDK */
            var storageAccountNewest = NEWEST_TABLE.CloudStorageAccount.Parse(connectionTableSAS);
            var tableClientNewest = storageAccountNewest.CreateCloudTableClient(new TableClientConfiguration());
            Debug.Assert(tableClientNewest.StorageUri.SecondaryUri != null); // demonstrate SecondaryUri initialised

            var tableRequestOptionsNewest = new NEWEST_TABLE.TableRequestOptions() { LocationMode = NEWEST_TABLE.LocationMode.SecondaryOnly };
            tableClientNewest.DefaultRequestOptions = tableRequestOptionsNewest;

            var tableNewset = tableClientNewest.GetTableReference("foo"); // don't need table to exist to show the issue
            var retrieveOperationNewset = NEWEST_TABLE.TableOperation.Retrieve(string.Empty, string.Empty, new List<string>() { "bar" });

            /* throws Microsoft.Azure.Cosmos.Table.StorageException
             * Exception thrown while initializing request: This operation can only be executed against the primary storage location
             */
            var tableResultNewset = tableNewset.Execute(retrieveOperationNewset);

            Console.WriteLine("Press any key to exit");
            Console.Read();
        }
    }
}

I believe you've encountered a bug with the SDK.我相信您遇到了 SDK 的错误。

When I try the following code, I get the same error as you:当我尝试以下代码时,我收到与您相同的错误:

        var account = CloudStorageAccount.Parse(connectionString);

        var requestOptions = new TableRequestOptions()
        {
            LocationMode = LocationMode.SecondaryOnly
        };
        var client = account.CreateCloudTableClient();
        client.DefaultRequestOptions = requestOptions;
        var table = client.GetTableReference("myTable");
        var op = TableOperation.Retrieve("", "");
        var result1 = table.Execute(op);

I decompiled the library code and found the culprit source code:我反编译了库代码,找到了罪魁祸首源代码:

if (commandLocationMode == CommandLocationMode.PrimaryOnly)
                {
                    if (restCMD.LocationMode == LocationMode.SecondaryOnly)
                    {
                        throw new InvalidOperationException("This operation can only be executed against the primary storage location.");//This is the error that gets thrown.
                    }
                    Logger.LogInformational(executionState.OperationContext, "This operation can only be executed against the primary storage location.", Array.Empty<object>());
                    executionState.CurrentLocation = StorageLocation.Primary;
                    restCMD.LocationMode = LocationMode.PrimaryOnly;
                }

However, if I don't set DefaultRequestOptions at client level and specify it below in Execute method, I don't get the error but then it's because the primary endpoint is hit instead of secondary (I checked that in Fiddler).但是,如果我不在客户端级别设置DefaultRequestOptions并在下面的Execute方法中指定它,我不会收到错误,但这是因为主端点被击中而不是次要端点(我在 Fiddler 中检查过)。

        var account = CloudStorageAccount.Parse(connectionString);

        var requestOptions = new TableRequestOptions()
        {
            LocationMode = LocationMode.SecondaryOnly
        };
        var client = account.CreateCloudTableClient();
        var table = client.GetTableReference("myTable");
        var op = TableOperation.Retrieve("", "");
        var result1 = table.Execute(op, requestOptions);

Workaround解决方法

If your objective is to query entities from secondary location, then you can use ExecuteQuery method on CloudTable like shown below.如果您的目标是从辅助位置查询实体,那么您可以在CloudTable上使用ExecuteQuery方法,如下所示。 This works (Again, I checked in Fiddler).这有效(同样,我检查了 Fiddler)。

        var account = CloudStorageAccount.Parse(connectionString);

        var requestOptions = new TableRequestOptions()
        {
            LocationMode = LocationMode.SecondaryOnly
        };
        var client = account.CreateCloudTableClient();
        client.DefaultRequestOptions = requestOptions;
        var table = client.GetTableReference("myTable");
        TableQuery query = new TableQuery();
        var result = table.ExecuteQuery(query).ToList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Azure 地理冗余 (RA-GRS) 表存储时,如何更新 ASP.NET 核心中的 TableServiceClient 以指向辅助区域? - How do you update TableServiceClient in ASP.NET Core, to point to a secondary region, when using Azure geo redundant (RA-GRS) table storage? Microsoft.Azure.Cosmos.Table 和 Microsoft.WindowsAzure.Storage 之间的 ExecuteQuerySegmentedAsync 性能显着下降 - Significant performance degration on ExecuteQuerySegmentedAsync between Microsoft.Azure.Cosmos.Table and Microsoft.WindowsAzure.Storage 在 Microsoft.Azure.Cosmos.Table 中使用 TableEntity.Flatten 的正确方法是什么? - What is the right way to use TableEntity.Flatten in Microsoft.Azure.Cosmos.Table? C# Azure - 从 Microsoft.Azure.Cosmos.Table 移动到 Azure.Data.Tables 后找不到指定的资源 - C# Azure - Specified Resource not found after moving from Microsoft.Azure.Cosmos.Table to Azure.Data.Tables Azure function 异常 - 将日志写入表存储时出错:Microsoft.Azure.Cosmos.Table.StorageException - Azure function exception - Error writing logs to table storage: Microsoft.Azure.Cosmos.Table.StorageException 抛出异常:'Microsoft.Azure.Cosmos.CosmosException',将 JSON 批量导入到 Z3A580F142203677F1F0BC30898F63F5Z Cosmos Cosmos 时出现错误请求 - Exception thrown: 'Microsoft.Azure.Cosmos.CosmosException', Bad Request while bulk importing JSON to Azure Cosmos DB Microsoft Azure存储表查询结果是否可以按属性值进行过滤 - Can the Microsoft Azure Storage Table query results filtering by property value Azure表存储异常处理 - Azure table storage exception handling 了解Select操作| Azure Cosmos DB 表 API - Understanding Select operation | Azure Cosmos DB Table API 无法将 Microsoft.Azure.Cosmos.Table.DynamicTableEntity 转换为 System.Threading.Task.Task <microsoft.azure.cosmos.table.dynamictableentity></microsoft.azure.cosmos.table.dynamictableentity> - Cannot convert Microsoft.Azure.Cosmos.Table.DynamicTableEntity to System.Threading.Task.Task<Microsoft.Azure.Cosmos.Table.DynamicTableEntity>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM