Hoje vamos falar sobre uma rotina que iremos criar em nosso ambiente para poder economizar com armazenamento de nossos backups.
Relembrando, o nosso cenário é o seguinte:
- Backup sendo realizados diretamente para um Storage General Porpose V1(GPV1);
- O Blob está indo com o tipo “page”;
- Temos que reter esses backups durante 3 meses;
- Passar o Blob do tipo Page do GPV1 para Storage Account “Blob” e acces tier Cool.
Como que realizaremos esses procedimentos, sendo que a Storage Account do tipo Blob não aceita o blobs do tipo“Page”?
Aqui eu tento passar o backup de um blob storage para outro através do “Microsoft Azure Storage Explorer”, porém é me retornado o erro:
Obs.: a stgcomunidadesqlserver1 é a storage account do tipo GPV1 e a stgcomunidadesqlserver0 é do tipo Blob.
Ao tentar passar via powershell com o comando “Start-AzureStorageBlobCopy” me retorna o mesmo erro e agora? Como que faço?
Simples! Basta converter o tipo do blob para block antes removê-lo, certo?
NO!
A gente especifica o tipo do blob quando o criamos e após isto, não é possível modificá-lo.
Desta forma, a solução seria utilizar o AZCopy para baixar este arquivo para meu servidor e depois realizar o Download novamente.
Aqui não irei detalhar sobre o AZCopy, mas para quem nunca o utilizou pode ter todos os detalhes no link: https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy
Login-AzureRmAccount #Passar as credenciais para acessar o Azure Set-AzureRmContext -SubscriptionName "SubscriptionName" #Preenche as variáveis para pegar os arquivos do Storage stgcomunidadesqlserver1 $SubscriptionName = "SubscriptionName" $ResourceName = "ComunidadeSQLServer" #Aqui eu coloco o nome do diretório para qual quero baixar meus backups $destFile = "E:\RotinaAzCopy" #storage account de origem $srcStorageAccount = "stgcomunidadesqlserver1" #Aqui estou pegando a access key da storage account para acessá-la $srcStorageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceName -StorageAccountName $srcStorageAccount).Value[0] $srcContext = New-AzureStorageContext -StorageAccountName $srcStorageAccount -StorageAccountKey $srcStorageKey #Conteiner de origem $srcContainer = "backup" $srcBlob = (Get-AzureStorageBlob -context $srcContext -Container $srcContainer) $srcBlob2 = $srcBlob.name #Muda de pasta para usar o AzCopy Set-Location "C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy" .\AzCopy.exe /Source:https://stgcomunidadesqlserver1.blob.core.windows.net/backup /Dest:$destFile /SourceKey:$srcStorageKey /Pattern:$srcBlob2 /Y
Resultado:
E para passar o Blob da pasta local para o Storage Account do tipo Blob basta executar:
#Aqui começa a parte de enviar os arquivos para o storage cold $coldStorageAccount = "stgcomunidadesqlserver0" $coldStorageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceName -StorageAccountName $coldStorageAccount).Value[0] $coldContext = New-AzureStorageContext -StorageAccountName $coldStorageAccount -StorageAccountKey $coldStorageKey .\AzCopy.exe /Source:$destFile /Dest:https://stgcomunidadesqlserver0.blob.core.windows.net/rotinamove /DestKey:$coldStorageKey /Y /S
Resultado:
Podemos observar que o “Access Tier” e o “Blob Type” já estão alterados. Isso porque nesta Storage Account o Access Tier padrão é o cool (configurei assim) e quando enviamos algum arquivo via AZCopy, o padrão dele é do tipo Block . Caso você queira mudar o tipo do blob ao fazer o upload dele, basta passar o parâmetro: /BlobType:”TipoDoBlob” , mas neste caso, não necessitamos de passar este parâmetro.
Então, juntando os dois, o comando completo ficaria assim:
Login-AzureRmAccount #Passar as credenciais para acessar o Azure Set-AzureRmContext -SubscriptionName "SubscriptonName" #Preenche as variáveis para pegar os arquivos do Storage stgcomunidadesqlserver1 $SubscriptionName = "SubscriptonName" $ResourceName = "ComunidadeSQLServer" #Aqui eu coloco o nome do diretório para qual quero baixar meus backups $destFile = "E:\RotinaAzCopy" #storage account de origem $srcStorageAccount = "stgcomunidadesqlserver1" #Aqui estou pegando a access key da storage account para acessá-la $srcStorageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceName -StorageAccountName $srcStorageAccount).Value[0] $srcContext = New-AzureStorageContext -StorageAccountName $srcStorageAccount -StorageAccountKey $srcStorageKey #Conteiner de origem $srcContainer = "backup" $srcBlob = (Get-AzureStorageBlob -context $srcContext -Container $srcContainer) $srcBlob2 = $srcBlob.name #Muda de pasta para usar o AzCopy Set-Location "C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy" .\AzCopy.exe /Source:https://stgcomunidadesqlserver1.blob.core.windows.net/backup /Dest:$destFile /SourceKey:$srcStorageKey /Pattern:$srcBlob2 /Y #Aqui começa a parter de enviar os arquivos para o storage cold $coldStorageAccount = "stgcomunidadesqlserver0" $coldStorageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceName -StorageAccountName $coldStorageAccount).Value[0] $coldContext = New-AzureStorageContext -StorageAccountName $coldStorageAccount -StorageAccountKey $coldStorageKey .\AzCopy.exe /Source:$destFile /Dest:https://stgcomunidadesqlserver0.blob.core.windows.net/rotinamove /DestKey:$coldStorageKey /Y /S
Porém, desta forma, estamos baixando somente um arquivo e se eu tiver vários arquivos a serem transferidos e com uma data de corte?
Nesta mesma lógica que utilizamos o AzCopy, vamos acrescentar o loop FOR e o Where-Object:
E o script vai ficar assim:
Login-AzureRmAccount #Passar as credenciais para acessar o Azure Set-AzureRmContext -SubscriptionName "SubscriptionName" #Preenche as variáveis para pegar os arquivos do Storage stgcomunidadesqlserver1 $SubscriptionName = "SubscriptionName" $ResourceName = "ComunidadeSQLServer" #Aqui eu coloco o nome do diretório para qual quero baixar meus backups $destFile = "E:\RotinaAzCopy" $srcStorageAccount = "stgcomunidadesqlserver1" #Aqui estou pegano a access key da storage account para acessá-la $srcStorageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceName -StorageAccountName $srcStorageAccount).Value[0] $srcContext = New-AzureStorageContext -StorageAccountName $srcStorageAccount -StorageAccountKey $srcStorageKey #Conteiner de origem $srcContainer = "backup" #colocar aqui a data de corte dos backups que deseja passar para o storage Cool. #Neste exemplo estamos passando a data com -7 dias $dataExclusao = (Get-Date).AddDays(-7) #Aqui acrescentaremos o Where-Object a data de corte que passamos na vareável anterior #Obs.: Para exemplo, comentei a parte do Where-Object, pois quis passar todos os backups do conteiner $srcBlob = (Get-AzureStorageBlob -context $srcContext -Container $srcContainer) | Where-Object {$_.LastModified -lt $dataExclusao} #Aqui estamos pegando somente o nome do blob, descartando as demais informações $srcBlob2 = $srcBlob.name #Aqui começa a parte de enviar os arquivos para o storage cood (Destino) $coldStorageAccount = "stgcomunidadesqlserver0" $coldStorageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceName -StorageAccountName $coldStorageAccount).Value[0] $coldContext = New-AzureStorageContext -StorageAccountName $coldStorageAccount -StorageAccountKey $coldStorageKey #Muda de pasta para usar o AzCopy Set-Location "C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy" #Na primeira execução, esta parte retornará um erro, pois os arquivos ainda não existirão #Estes arquivos criei para verificar se minha rotina foi com sucesso ou não Remove-Item E:\ResultadoRotinaAzCopy\resultadoQuente.txt -recurse -Confirm:$false Remove-Item E:\ResultadoRotinaAzCopy\resultadoFrio.txt -recurse -Confirm:$false #Aqui estpu pegando somente a quantidade de arquivos e logando $srcBlob2.Count | Out-File E:\ResultadoRotinaAzCopy\resultadoQuente.txt -append #Utilizaremos esta data para futuras verificações #Importante lembrar que a timezone do servidor deverá ser a mesma do azure, pois aqui estamos usando a data como filtro $DataInicio = (Get-Date) #Cria um loop para baixar somente os arquivos que eu quero for ($i=0; $i -lt $srcBlob2.Count; $i++) { #Nas duas próximas linhas passo o arquivo na posição do array, jogo na variável e depois logo no meu arquivo .txt $file = $srcBlob2[$i] $file | Out-File E:\ResultadoRotinaAzCopy\resultadoQuente.txt -append #Aqui começo o procedimento do download do meu backup e logo novamente o resultado. #Observar que desta vez estamos passando o parâmetro /Pattern: , pois queremos pegar somente um arquivo. .\AzCopy.exe /Source:https://stgcomunidadesqlserver1.blob.core.windows.net/backup /Dest:$destFile /SourceKey:$srcStorageKey /Pattern:$file /Y | Out-File E:\ResultadoRotinaAzCopy\resultadoQuente.txt -append $file | Out-File E:\ResultadoRotinaAzCopy\resultadoFrio.txt -append #Aqui começo o meu upload para o blob de destino .\AzCopy.exe /Source:$destFile /Dest:https://stgcomunidadesqlserver0.blob.core.windows.net/rotinamove /DestKey:$coldStorageKey /Y | Out-File E:\ResultadoRotinaAzCopy\resultadoFrio.txt -append Remove-Item $destFile -recurse -Confirm:$false } #Importante lembrar que a timezone do servidor deverá ser a mesma do azure, pois aqui estamos usando a data como filtro $ResultadoCold = (Get-AzureStorageBlob -context $coldContext -Container "rotinamove" | Where-Object {$_.LastModified -ge $DataInicio}) $resultadoCold2 = $resultadoCold.name $TamanhoCold = $resultadoCold2.Count $tamanhoHot = $srcBlob2.Count #Aqui realizaremos uma simples verificação se todos os blobs do período que quis passar foram com sucesso. #Caso positivo, os blobs da origem serão excluídos IF($TamanhoCold -eq $tamanhoHot) { Get-AzureStorageBlob -context $srcContext -Container $srcContainer | Where-Object {$_.LastModified -le $dataExclusao} | Remove-AzureStorageBlob | Out-file F:\Resultado\ErroDelete.txt }
Blob de Origem:
Blob de destino:
Ficando com a nossa arquitetura final:
Para completar, como queremos deixar isso automático, podemos criar um job no Agent (isso mesmo, dentro do SQL Server) para que todos os dias as “X” horas essa rotina é executada. A única diferença é que no comando Login-AzureRmAccount já tenhamos que passar as credenciais. Talvez isso seja uma “falha” se segurança, mas levando em consideração que somente pessoas autorizadas terão acesso aos jobs, e que a conta que será configurada tiver somente o acesso restrito à movimentação de arquivos entre as storage accounts, certamente não teremos problemas com segurança!
Acrescentando o código assim:
$Usuario = "sqlazure@seudominio.onmicrosoft.com" $secpasswd = ConvertTo-SecureString "senha" -AsPlainText -Force $mycreds = New-Object -typename System.Management.Automation.PSCredential -ArgumentList $Usuario,$secpasswd #Loga no Azure Login-AzureRmAccount -Credential $mycreds
Desta forma, espero que não tenha ficado confuso os scripts (ainda tenho que melhorar e muito em minhas documentações de códigos rsrs), mas qualquer dúvida estou disponível para responder.
Até o próximo post: “Limitações/Erros (Access Key Credential)“
Pingback: BACKUP DATABASE DB TO URL = ‘BLOB STORAGE’ – Comunidade SQL Server
Pingback: Limitações/Erros (Access Key Credential) – Comunidade SQL Server