Condividi tramite


Il caricamento di contenuto BLOB o blocchi non riesce in Archiviazione BLOB di Azure

Questo articolo illustra come risolvere gli errori che possono verificarsi quando si usa Microsoft Archiviazione BLOB di Azure insieme alle applicazioni cloud per caricare contenuto BLOB o blocchi.

Prerequisiti

Sintomi

Viene visualizzato uno dei messaggi di errore seguenti.

Codice di errore Error message
BlockCountExceedsLimit "Il numero di blocchi di cui non è stato eseguito il commit non può superare il limite massimo di 100.000 blocchi".
InvalidBlobOrBlock "Il contenuto del BLOB o del blocco specificato non è valido".
InvalidBlock o InvalidBlockList "L'elenco di blocchi specificato non è valido".

Causa 1: La lunghezza del blocco specificata nella chiamata Put Block non è valida

La lunghezza del blocco specificata nella richiesta Put Block URI non è valida per uno o più dei motivi seguenti:

  • L'applicazione o il client ha specificato una dimensione del blocco non supportata.

  • La dimensione del blocco è maggiore della dimensione massima consentita del blocco. Per trovare i limiti delle dimensioni dei blocchi per versioni diverse dell'API REST del servizio BLOB, vedere la sezione Osservazioni dell'articolo di riferimento "Put Block".

  • Quando si tenta di caricare blocchi di dati usando più di un'applicazione, sono presenti blocchi di cui non è stato eseguito il commit con lunghezze di blocchi incoerenti. Questa situazione si verifica perché diverse applicazioni usano lunghezze diverse per caricare i dati o perché un caricamento precedente non è riuscito.

  • Il BLOB ha troppi blocchi di cui non è stato eseguito il commit perché è stata annullata un'operazione di caricamento precedente. Il numero massimo di blocchi di cui non è possibile eseguire il commit è 100.000.

Rimuovere i blocchi di cui non è stato eseguito il commit implementando una di queste soluzioni.

Soluzione 1: Attendere che Garbage Collection rilevi i dati di cui non è stato eseguito il commit

Attendere sette giorni prima che l'elenco di blocchi di cui non è stato eseguito il commit venga pulito da Garbage Collection.

Soluzione 2: Usare un BLOB fittizio per eseguire il trasferimento dei dati

Usare Archiviazione di Azure SDK per trasferire i dati usando un BLOB fittizio. A tale scopo, effettuare i passaggi seguenti:

  1. Creare un BLOB fittizio con lo stesso nome di BLOB e che si trova nello stesso contenitore. Questo BLOB può avere una lunghezza pari a zero.

  2. Trasferire il BLOB usando un trasferimento sbloccato.

Soluzione 3: Eseguire il commit dell'elenco di blocchi di cui non è stato eseguito il commit usando Archiviazione di Azure SDK

Usare Archiviazione di Azure SDK per eseguire il commit dell'elenco di blocchi di cui non è stato eseguito il commit e pulire il BLOB. A tale scopo, effettuare i passaggi seguenti:

  1. Recuperare l'elenco di blocchi di cui non è stato eseguito il commit eseguendo una richiesta Get Block List URI in cui il blocklisttype parametro URI è impostato su uncommitted.

  2. Eseguire il commit dell'elenco di blocchi usando la richiesta Put Block List URI.

  3. Eliminare il BLOB.

La funzione di PowerShell seguente è un esempio di come recuperare un elenco di blocchi di cui non è stato eseguito il commit e quindi eliminarlo. La funzione richiede i parametri seguenti.

Nome parametro Descrizione
-StorageAccountName Nome dell'account di archiviazione.
-SharedAccessSignature Token di firma di accesso condiviso (SAS) che usa i parametri <ss=b;srt=sco;sp=rwldc>URI . Questi parametri sono descritti in Costruire un URI di firma di accesso condiviso dell'account.
-ContainerName Nome del contenitore di archiviazione.
-BlobName Nome del 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."
)

Causa 2: le operazioni PUT si verificano simultaneamente per un BLOB

Si verifica un problema di temporizzazione o concorrenza. In questo modo si verificano più operazioni PUT (Put Block) contemporaneamente per un singolo BLOB. L'operazione Put Block List scrive un BLOB specificando l'elenco di ID blocchi che costituiscono il BLOB. Per essere scritto come parte di un BLOB, è necessario che un blocco sia stato scritto correttamente nel server in un'operazione Put Block precedente.

Note

Questo errore può verificarsi durante i commit di caricamento simultanei dopo l'avvio del caricamento, ma prima del commit. In questo caso, il caricamento non riesce. L'applicazione può ritentare il caricamento quando si verifica l'errore oppure provare un'altra azione di ripristino basata sullo scenario richiesto.

Soluzione: usare i lease

Invece di usare la concorrenza ottimistica, provare a implementare la concorrenza pessimistica (lease) usando Archiviazione di Azure SDK o uno strumento basato su GUI, ad esempio Archiviazione di Azure Explorer. Per altre informazioni sulla concorrenza ottimistica e pessimistica, vedere Gestione della concorrenza nell'archiviazione BLOB.

Se l'errore è causato da problemi di concorrenza, potrebbe anche essere necessario pulire i blocchi di cui non è stato eseguito il commit seguendo una delle soluzioni in Causa 1.

Contattaci per ricevere assistenza

In caso di domande o bisogno di assistenza, creare una richiesta di supporto tecnico oppure formula una domanda nel Supporto della community di Azure. È possibile anche inviare un feedback sul prodotto al feedback della community di Azure.