O objetivo
Manter dois bancos de dados sincronizados é uma tarefa que frequentemente encontramos ao trabalhar no desenvolvimento e manutenção do banco de dados SQL. Um caso particular é este – as versões de um banco de dados presentes em ambientes de teste e desenvolvimento precisam ser sincronizadas de forma consistente para garantir que os testes sejam executados na versão mais recente. Isso deve ser feito detectando alterações de esquema na versão de desenvolvimento de um banco de dados e, em seguida, sincronizando-as automaticamente com a versão do ambiente de teste de forma programada.
Como conseguir
Veremos como a sincronização automatizada de dois bancos de dados SQL pode ser alcançada combinando uma ferramenta de comparação de esquema com scripts e agendamento do PowerShell.
No exemplo que veremos, os bancos de dados serão sincronizados a cada 15 minutos. Como estamos usando uma ferramenta de comparação de esquemas, podemos ter certeza de que o banco de dados só será atualizado se houver algumas mudanças reais entre as versões de desenvolvimento e teste do banco de dados – isso evita a execução de operações desnecessárias com muitos recursos.
Usaremos o Devart Schema Compare como o utilitário de escolha para diferenciar e sincronizar bancos de dados SQL Server. É uma ferramenta que permite comparar e sincronizar bancos de dados, instantâneos e backups do SQL Server ao vivo. Vamos ver como podemos implementar nosso projeto abaixo.
Configuração
Antes de tudo, precisamos configurar algumas coisas:
- Executar comparação de esquema
- Clique em 'Nova comparação de esquema ' botão na barra de ferramentas ou, alternativamente, na parte superior direita da página inicial:
- Na Origem e Destino guia da Nova comparação de esquema janela, escolha os bancos de dados de origem e destino desejados:
- Nas Opções , Mapeamento de esquema e Mapeamento de tabela guias, você pode configurar as opções de comparação e sincronização necessárias:
- Quando tudo estiver configurado, você pode pressionar o botão 'Comparar ' botão no canto inferior direito para iniciar o processo de comparação.
- Quando a comparação terminar, você poderá ver todos os objetos que foram comparados e seus respectivos status de diferença na parte superior da janela, enquanto o script detalhado para cada um desses objetos estará localizado na parte inferior:
- Marque todos os objetos para incluí-los no processo de sincronização e clique no botão 'Salvar ' botão ou pressione Arquivo> Salvar :Isso salvará o projeto com todas as informações necessárias para iniciar o processo de sincronização.
- Depois que o projeto for salvo, clique no botão ‘Sincronizar objetos ' botão:
- Assistente de sincronização de esquema será aberto. Primeiro, selecione ‘Execute o script diretamente no banco de dados de destino ‘ na Saída aba:
- Você pode escolher as configurações necessárias nas Opções aba:
- Você pode verificar todos os objetos que serão sincronizados no Resumo aba:
- Clique em 'Sincronizar ' no canto inferior direito para testar o processo de sincronização.
- Você verá os resultados exibidos no painel inferior da janela:
Automatizando o processo
Como a sincronização do esquema foi bem-sucedida e agora que temos um arquivo de projeto com todas as informações necessárias, vamos automatizar o processo de sincronização usando um script do PowerShell.
No exemplo a seguir, supõe-se que você use a segurança integrada, mas o banco de dados armazenado e criptografado ainda pode ser facilmente acessado a partir do arquivo de projeto, juntamente com as credenciais do repositório.
Veremos algumas partes do processo de criação do script que podem ser particularmente interessantes, mas sinta-se à vontade para pular esta seção para baixar e testar o script finalizado imediatamente.
Criando um script
Primeiro, precisaremos criar uma função que verifique se a pasta Outputs existe. O objetivo desta pasta é armazenar resumos de confirmação com carimbo de dados. A função deve ficar assim:
#check if the Outputs folder exists function CheckAndCreateFolder($rootFolder, [switch]$Outputs) { $location = $rootFolder #setting up its location if($Outputs -eq $true) { $location += "\Outputs" } #creating the folder if it doesn't currently exist if(-not (Test-Path $location)) { mkdir $location -Force:$true -Confirm:$false | Out-Null } return $location }
Em seguida, definiremos a pasta raiz e o local dos resumos de saída do esquema:
#defining the root folder for the synchronization process $rootFolder = "d:\temp\SchemaSync" #defining the location of schema output summaries $outsLoc = CheckAndCreateFolder $rootFolder -Outputs
Agora, precisaremos definir a localização do Schema Compare, a variável do carimbo de data e os parâmetros da aplicação:
#Schema Compare location and the date stamp variable are defined, as well as the tool’s parameters $diffLoc = "C:\Program Files\Devart\dbForge Studio for SQL Server\dbforgesql.com" $stamp = (Get-Date -Format "Mmddyyyy_HHMMss")
Com isso em vigor, podemos definir o caminho para o arquivo de log de saída:
#output log file path $logPath = "$outsLoc\SchemaOutput_$stamp.txt" $Params = "/schemacompare /compfile:""D:\temp\SchemaSync\Project\AdventureWorksLTDvsAdventureWorksDW.scomp"" /log:""$logPath""" $sync = " /sync"
Em seguida, vamos chamar Schema Compare e deixá-lo executar seus parâmetros de sincronização:
#initiate the schema comparison and synchronization process (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params)) $returnCode = $LASTEXITCODE $message = ""
A parte final do roteiro servirá para definir todos os resultados possíveis:
- Alterações de esquema são detectadas, código de retorno 0 – Sucesso
- Nenhuma alteração de esquema detectada, código de retorno 100– Nenhuma alteração de esquema detectada
- Um erro foi encontrado e o resumo de saída será aberto.
if ($returnCode -notin (100, 101)) { #an error is encountered $logPath = "$outsLoc\SchemaOutput_error.txt" $message >> $logPath clear-content $logPath $message = "`r`n $returnCode - An error is encountered" #output file is opened when an error is encountered Invoke-Item "$logPath" } else{ if ($returnCode -eq 101) { clear-content $logPath (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params+$sync)) $returnCode = $LASTEXITCODE #schema changes are detected } if($returnCode -eq 0) { $message = "`r`n $returnCode - Schema changes were successfully synchronized" } else { #there are no schema changes if($returnCode -eq 100) { $message = "`r`n $returnCode - There are no schema changes. Job aborted" } } } $message >> $logPath
Programação
Com o script do PowerShell pronto e o processo automatizado, podemos agendar isso de algumas maneiras diferentes, por exemplo. através do Agendador do Windows.
Visualizando resultados
Agora que o trabalho agendado está em execução, você pode visualizar os resumos de saída do esquema sempre que precisar. No exemplo que acabamos de ver, a variável $outsLoc definiu a localização dos resumos de saída do esquema. Como resultado, esses resumos serão salvos em $rootFolder\$outsLoc – neste caso específico, SchemaSync\Outputs:
Se algum erro for encontrado, por exemplo, a extensão de um arquivo de projeto for inserida incorretamente, a mensagem de erro correspondente será exibida no resumo de saída.
A lista de códigos de erro de retorno nos ajudará a entender melhor o erro específico que encontramos.
[expandir título ="SCRIPT COMPLETO “]
#check if the Outputs folder exists function CheckAndCreateFolder($rootFolder, [switch]$Outputs) { $location = $rootFolder #setting up its location if($Outputs -eq $true) { $location += "\Outputs" } #creating the folder if it doesn't currently exist if(-not (Test-Path $location)) { mkdir $location -Force:$true -Confirm:$false | Out-Null } return $location } #defining the root folder for the synchronization process $rootFolder = "d:\temp\SchemaSync" #defining the location of schema output summaries $outsLoc = CheckAndCreateFolder $rootFolder -Outputs #Schema Compare location and the date stamp variable are defined, as well as the tool’s parameters $diffLoc = "C:\Program Files\Devart\dbForge Studio for SQL Server\dbforgesql.com" $stamp = (Get-Date -Format "Mmddyyyy_HHMMss") #output log file path $logPath = "$outsLoc\SchemaOutput_$stamp.txt" $Params = "/schemacompare /compfile:""D:\temp\SchemaSync\Project\AdventureWorksLTDvsAdventureWorksDW.scomp"" /log:""$logPath""" $sync = " /sync" #initiate the schema comparison and synchronization process (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params)) $returnCode = $LASTEXITCODE $message = "" if ($returnCode -notin (100, 101)) { #an error is encountered $logPath = "$outsLoc\SchemaOutput_error.txt" $message >> $logPath clear-content $logPath $message = "`r`n $returnCode - An error is encountered" #output file is opened when an error is encountered Invoke-Item "$logPath" } else{ if ($returnCode -eq 101) { clear-content $logPath (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params+$sync)) $returnCode = $LASTEXITCODE #schema changes are detected } if($returnCode -eq 0) { $message = "`r`n $returnCode - Schema changes were successfully synchronized" } else { #there are no schema changes if($returnCode -eq 100) { $message = "`r`n $returnCode - There are no schema changes. Job aborted" } } } $message >> $logPath
[/expandir]
Se surgirem dúvidas ou problemas durante o processo de configuração, sinta-se à vontade para nos contatar a qualquer momento em [email protected]