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
- Un account di archiviazione da uno dei servizi di archiviazione seguenti:
- ARCHIVIAZIONE DI AZURE SDK
- Azure Storage Explorer
- PowerShell
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:
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.
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:
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 suuncommitted
.Eseguire il commit dell'elenco di blocchi usando la richiesta Put Block List URI.
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.