BLOB またはブロック コンテンツのアップロードがAzure Blob Storageで失敗する

この記事では、クラウド アプリケーションと共に Microsoft Azure Blob Storageを使用して BLOB をアップロードしたり、コンテンツをブロックしたりするときに発生する可能性があるエラーを解決する方法について説明します。

前提条件

現象

次のいずれかのエラー メッセージが表示されます。

エラー コード エラー メッセージ
BlockCountExceedsLimit "コミットされていないブロック数は、100,000 ブロックの上限を超えることはできません。
InvalidBlobOrBlock "指定された BLOB またはブロック コンテンツが無効です。
InvalidBlock または InvalidBlockList "指定されたブロック リストが無効です。

原因 1: Put Block 呼び出しで指定されたブロック長が無効です

Put Block URI 要求で指定されたブロック長は、次の 1 つ以上の理由で有効ではありません。

  • アプリケーションまたはクライアントが、サポートされていないブロック サイズを指定しました。

  • ブロックのサイズが、許可される最大ブロック サイズを超えています。 Blob Service REST API の異なるバージョンのブロック サイズ制限を確認するには、"Put Block" リファレンス記事の 「解説 」セクションを参照してください。

  • 複数のアプリケーションを使用してデータ ブロックをアップロードしようとすると、ブロック長が一貫性のないコミットされていないブロックがありました。 この状況は、異なるアプリケーションが異なる長さを使用してデータをアップロードするため、または以前のアップロードが失敗したために発生します。

  • 以前のアップロード操作が取り消されたため、BLOB にコミットされていないブロックが多すぎます。 BLOB に関連付けることができるコミットされていないブロックの最大数は 100,000 です。

これらのソリューションのいずれかを実装して、コミットされていないブロックを削除します。

解決策 1: ガベージ コレクションがコミットされていないデータを取得するまで待つ

コミットされていないブロック リストがガベージ コレクションによってクリーンアップされるまで 7 日間待ちます。

解決策 2: ダミー BLOB を使用してデータ転送を行う

ダミー BLOB を使用してデータを転送するには、Azure Storage SDK を使用します。 これを行うには、次の手順を実行します。

  1. 同じ BLOB 名を持ち、同じコンテナー内にあるダミー BLOB を作成します。 この BLOB の長さは 0 にすることができます。

  2. ブロック解除された転送を使用して BLOB を転送します。

解決策 3: Azure Storage SDK を使用してコミットされていないブロック リストをコミットする

Azure Storage SDK を使用して、コミットされていないブロック リストをコミットし、BLOB をクリーンします。 これを行うには、次の手順を実行します。

  1. URI パラメーターが に設定されている Get Block List URI 要求 blocklisttype を作成して、コミットされていないブロック リストを uncommitted取得します。

  2. ブロック リストの書き込み URI 要求を使用して 、ブロック リストをコミットします

  3. BLOB を削除します。

次の PowerShell 関数は、コミットされていないブロック リストを取得して削除する方法の例です。 関数には、次のパラメーターが必要です。

パラメーター名 説明
-StorageAccountName ストレージ アカウントの名前。
-SharedAccessSignature URI パラメーター <ss=b;srt=sco;sp=rwldc>を使用する共有アクセス署名 (SAS) トークン。 これらのパラメーターについては、「 アカウント SAS URI の構築」を参照してください。
-ContainerName ストレージ コンテナーの名前。
-BlobName BLOB の名前。
[CmdletBinding()] Param(
    [Parameter(Mandatory=$true, Position=1)] [string] $StorageAccountName,
    [Parameter(Mandatory=$True, Position=1)] [string] $SharedAccessSignature,
    [Parameter(Mandatory=$True, Position=1)] [string] $ContainerName,
    [Parameter(Mandatory=$True, Position=1)] [string] $BlobName
)

# Build the URI strings in the REST API for GET and DELETE.
$uriDelete = (
    "https://$StorageAccountName.blob.core.windows.net/",
    "$ContainerName",
    "/",
    "$BlobName",
    "$SharedAccessSignature"
) -Join ""
$uriGet = (
    "$uriDelete",
    "&comp=blocklist",
    "&blocklisttype=uncommitted"
) -Join ""
Write-Host "The Delete URI is $uriDelete."
Write-Host "The Get URI is $uriGet."

# Make a REST API call to get the uncommitted block list.
$listFileURI = Invoke-WebRequest -Uri $uriGet -Method Get
$FileSystemName = $listFileURI.Content
$String = $FileSystemName -replace '' , ''
$String |
    Select-Xml –XPath "/BlockList/UncommittedBlocks/Block" |
        Select-Object -Expand Node
$Count = $String.Count

# Delete the blob and the uncommitted block.
if ($Count.Count -gt 0) {
    $listFileURI1 =  Invoke-WebRequest -Uri $uriDelete -Method Delete
    $FileSystemName1 = $listFileURI1.StatusCode
    Write-Host "The deletion was successful. The API returned status code $FileSystemName1."
}

Write-Host "Check whether the uncommitted blocks are still present."
Try {
    $listFileURI2 = Invoke-WebRequest -Uri $uriGet -Method Get
} Catch {
    # $err = $_.Exception
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
}

Write-Host (
    "In this error message, we can verify that the",
    "uncommitted blocks and their respective blob have been deleted.",
    "The name and size of the uncommitted blocks that have been deleted are shown."
)

原因 2: BLOB に対して PUT 操作が同時に発生する

タイミングまたはコンカレンシーの問題が発生します。 これにより、1 つの BLOB に対して複数の PUT (Put Block) 操作が同時に実行されます。 Put Block List 操作では、BLOB を構成するブロック ID の一覧を指定して BLOB を書き込みます。 BLOB の一部として書き込まれるには、前の Put Block 操作でブロックがサーバーに正常に書き込まれている必要があります。

注:

このエラーは、アップロードを開始した後、コミットする前に、同時アップロードコミット中に発生する可能性があります。 この場合、アップロードは失敗します。 アプリケーションは、エラーが発生したときにアップロードを再試行するか、必要なシナリオに基づいて別の回復アクションを試すことができます。

解決策: リースを使用する

オプティミスティック コンカレンシーを使用する代わりに、Azure Storage SDK または GUI ベースのツール (Azure Storage Explorer など) を使用して、悲観的なコンカレンシー (リース) を実装してみてください。 オプティミスティックコンカレンシーとペシミスティックコンカレンシーの詳細については、「 BLOB ストレージでのコンカレンシーの管理」を参照してください。

エラーがコンカレンシーの問題によって引き起こされる場合は、「原因 1」のいずれかの解決策に従って、コミットされていないブロックをクリーンしなければならない場合もあります。

お問い合わせはこちらから

質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。