Usar o PowerShell para sincronização entre vários bancos de dados SQLUse PowerShell to sync between multiple SQL Databases

Este exemplo do PowerShell configura a Sincronização de Dados para sincronização entre vários bancos de dados SQL do Azure.This PowerShell example configures Data Sync to sync between multiple Azure SQL databases.

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.If you don't have an Azure subscription, create a free account before you begin.

Observação

Este artigo foi atualizado para usar o novo módulo Az do Azure PowerShell.This article has been updated to use the new Azure PowerShell Az module. Você ainda pode usar o módulo AzureRM, que continuará a receber as correções de bugs até pelo menos dezembro de 2020.You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. Para saber mais sobre o novo módulo Az e a compatibilidade com o AzureRM, confira Apresentação do novo módulo Az do Azure PowerShell.To learn more about the new Az module and AzureRM compatibility, see Introducing the new Azure PowerShell Az module. Para obter instruções de instalação do módulo Az, confira Instalar o Azure PowerShell.For Az module installation instructions, see Install Azure PowerShell.

Usar o Azure Cloud ShellUse Azure Cloud Shell

O Azure hospeda o Azure Cloud Shell, um ambiente de shell interativo que pode ser usado por meio do navegador.Azure hosts Azure Cloud Shell, an interactive shell environment that you can use through your browser. O Cloud Shell permite usar bash ou PowerShell para trabalhar com serviços do Azure.Cloud Shell lets you use either bash or PowerShell to work with Azure services. É possível usar os comandos pré-instalados do Cloud Shell para executar o código neste artigo sem precisar instalar nada no seu ambiente local.You can use the Cloud Shell pre-installed commands to run the code in this article without having to install anything on your local environment.

Para iniciar o Azure Cloud Shell:To launch Azure Cloud Shell:

OpçãoOption Exemplo/LinkExample/Link
Selecione Experimente no canto superior direito de um bloco de código.Select Try It in the upper-right corner of a code block. Selecionar Experimente não copia automaticamente o código para o Cloud Shell.Selecting Try It doesn't automatically copy the code to Cloud Shell. Exemplo de “Experimente” no Azure Cloud Shell
Acesse https://shell.azure.com ou clique no botão Iniciar o Cloud Shell para abri-lo no navegador.Go to https://shell.azure.com or select the Launch Cloud Shell button to open Cloud Shell in your browser. Inicie o Cloud Shell em uma nova janelaLaunch Cloud Shell in a new window
Clique no botão Cloud Shell na barra de menus no canto superior direito do portal do Azure.Select the Cloud Shell button on the top-right menu bar in the Azure portal. Botão Cloud Shell no portal do Azure

Para executar o código neste artigo no Azure Cloud Shell:To run the code in this article in Azure Cloud Shell:

  1. Inicie o Cloud Shell.Launch Cloud Shell.

  2. Clique no botão Copiar no bloco de código para copiá-lo.Select the Copy button on a code block to copy the code.

  3. Cole o código na sessão do Cloud Shell com Ctrl+Shift+V no Windows e no Linux ou Cmd+Shift+V no macOS.Paste the code into the Cloud Shell session with Ctrl+Shift+V on Windows and Linux, or Cmd+Shift+V on macOS.

  4. Pressione Enter para executar o código.Press Enter to run the code.

Se você optar por instalar e usar o PowerShell localmente, este tutorial exigirá o AZ PowerShell 1.4.0 ou posterior.If you choose to install and use the PowerShell locally, this tutorial requires AZ PowerShell 1.4.0 or later. Se você precisa atualizar, consulte Instalar o módulo do Azure PowerShell.If you need to upgrade, see Install Azure PowerShell module. Se você estiver executando o PowerShell localmente, também precisará executar o Connect-AzAccount para criar uma conexão com o Azure.If you are running PowerShell locally, you also need to run Connect-AzAccount to create a connection with Azure.

Para obter uma visão geral da Sincronização de Dados SQL, consulte Sincronizar dados entre vários bancos de dados locais e de nuvem com a Sincronização de Dados SQL do Azure.For an overview of SQL Data Sync, see Sync data across multiple cloud and on-premises databases with Azure SQL Data Sync.

Importante

No momento, a Sincronização de Dados SQL do Azure não dá suporte à Instância Gerenciada do Banco de Dados SQL do Azure.Azure SQL Data Sync does not support Azure SQL Database Managed Instance at this time.

Script de exemploSample script

# prerequisites: 
# 1. Create an Azure SQL Database from AdventureWorksLT sample database as hub database
# 2. Create an Azure SQL Database in the same region as sync database
# 3. Create an Azure SQL Database as member database
# 4. Update the parameters below before running the sample
#
using namespace Microsoft.Azure.Commands.Sql.DataSync.Model
using namespace System.Collections.Generic

# Hub database info
# Subscription id for hub database
$SubscriptionId = "subscription_guid"
# Resource group name for hub database
$ResourceGroupName = "ResourceGroup"
# Server name for hub database
$ServerName = "Server"
# Database name for hub database
$DatabaseName = "AdventureWorks"

# Sync database info
# Resource group name for sync database
$SyncDatabaseResourceGroupName = "ResourceGroup"
# Server name for sync database
$SyncDatabaseServerName = "Server"
# Sync database name
$SyncDatabaseName = "SyncDatabase"

# Sync group info
# Sync group name
$SyncGroupName = "SampleSyncGroup1"
# Conflict resolution Policy. Value can be HubWin or MemberWin
$ConflictResolutionPolicy = "HubWin"
# Sync interval in seconds. Value must be no less than 300
$IntervalInSeconds = 300

# Member database info
# Member name
$SyncMemberName = "member"
# Member server name
$MemberServerName = "MemberServer"
# Member database name
$MemberDatabaseName = "SyncDatabase1"
# Member database type. Value can be AzureSqlDatabase or SqlServerDatabase
$MemberDatabaseType = "AzureSqlDatabase"
# Sync direction. Value can be Bidirectional, Onewaymembertohub, Onewayhubtomember
$SyncDirection = "Bidirectional"

# Other info
# Temp file to save the sync schema
$TempFile = $env:TEMP+"\syncSchema.json"

# List of included columns and tables in quoted name
$IncludedColumnsAndTables =  "[SalesLT].[Address].[AddressID]",
                             "[SalesLT].[Address].[AddressLine2]",
                             "[SalesLT].[Address].[rowguid]",
                             "[SalesLT].[Address].[PostalCode]",
                             "[SalesLT].[ProductDescription]"
$MetadataList = [System.Collections.ArrayList]::new($IncludedColumnsAndTables)


Connect-AzAccount 
select-Azsubscription -SubscriptionId $SubscriptionId

# Use this section if it is safe to show password in the script.
# Otherwise, use the PromptForCredential
# $User = "username"
# $PWord = ConvertTo-SecureString -String "Password" -AsPlainText -Force
# $Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $PWord

$Credential = $Host.ui.PromptForCredential("Need credential", 
              "Please enter your user name and password for server "+$ServerName+".database.windows.net", 
              "", 
              "")

# Create a new sync group
Write-Host "Creating Sync Group"$SyncGroupName
New-AzSqlSyncGroup   -ResourceGroupName $ResourceGroupName `
                            -ServerName $ServerName `
                            -DatabaseName $DatabaseName `
                            -Name $SyncGroupName `
                            -SyncDatabaseName $SyncDatabaseName `
                            -SyncDatabaseServerName $SyncDatabaseServerName `
                            -SyncDatabaseResourceGroupName $SyncDatabaseResourceGroupName `
                            -ConflictResolutionPolicy $ConflictResolutionPolicy `
                            -DatabaseCredential $Credential

# Use this section if it is safe to show password in the script.
#$User = "username"
#$Password = ConvertTo-SecureString -String "password" -AsPlainText -Force
#$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $Password

$Credential = $Host.ui.PromptForCredential("Need credential", 
              "Please enter your user name and password for server "+$MemberServerName, 
              "", 
              "")

# Add a new sync member
# You can add members from other subscriptions, you don't need to specify Subscription Id for the member
Write-Host "Adding member"$SyncMemberName" to the sync group"
New-AzSqlSyncMember   -ResourceGroupName $ResourceGroupName `
                            -ServerName $ServerName `
                            -DatabaseName $DatabaseName `
                            -SyncGroupName $SyncGroupName `
                            -Name $SyncMemberName `
                            -MemberDatabaseCredential $Credential `
                            -MemberDatabaseName $MemberDatabaseName `
                            -MemberServerName ($MemberServerName + ".database.windows.net") `
                            -MemberDatabaseType $MemberDatabaseType `
                            -SyncDirection $SyncDirection

# Refresh database schema from hub database
# Specify the -SyncMemberName parameter if you want to refresh schema from the member database
Write-Host "Refreshing database schema from hub database"
$StartTime= Get-Date
Update-AzSqlSyncSchema   -ResourceGroupName $ResourceGroupName `
                              -ServerName $ServerName `
                              -DatabaseName $DatabaseName `
                              -SyncGroupName $SyncGroupName


#Waiting for successful refresh

$StartTime=$StartTime.ToUniversalTime()
$timer=0
$timeout=90
# Check the log and see if refresh has gone through
Write-Host "Check for successful refresh"
$IsSucceeded = $false
While ($IsSucceeded -eq $false)
{
    Start-Sleep -s 10
    $timer=$timer+10
    $Details = Get-AzSqlSyncSchema -SyncGroupName $SyncGroupName -ServerName $ServerName -DatabaseName $DatabaseName -ResourceGroupName $ResourceGroupName
    if ($Details.LastUpdateTime -gt $StartTime)
      {
        Write-Host "Refresh was successful"
        $IsSucceeded = $true
      }
    if ($timer -eq $timeout) 
      {
              Write-Host "Refresh timed out"
        break;
      }
}



# Get the database schema 
Write-Host "Adding tables and columns to the sync schema"
$databaseSchema = Get-AzSqlSyncSchema   -ResourceGroupName $ResourceGroupName `
                                             -ServerName $ServerName `
                                             -DatabaseName $DatabaseName `
                                             -SyncGroupName $SyncGroupName `

$databaseSchema | ConvertTo-Json -depth 5 -Compress | Out-File "c:\tmp\databaseSchema"     
$newSchema = [AzureSqlSyncGroupSchemaModel]::new()
$newSchema.Tables = [List[AzureSqlSyncGroupSchemaTableModel]]::new();

# Add columns and tables to the sync schema
foreach ($tableSchema in $databaseSchema.Tables)
{
    $newTableSchema = [AzureSqlSyncGroupSchemaTableModel]::new()
    $newTableSchema.QuotedName = $tableSchema.QuotedName
    $newTableSchema.Columns = [List[AzureSqlSyncGroupSchemaColumnModel]]::new();
    $addAllColumns = $false
    if ($MetadataList.Contains($tableSchema.QuotedName))
    {
        if ($tableSchema.HasError)
        {
            $fullTableName = $tableSchema.QuotedName
            Write-Host "Can't add table $fullTableName to the sync schema" -foregroundcolor "Red"
            Write-Host $tableSchema.ErrorId -foregroundcolor "Red"
            continue;
        }
        else
        {
            $addAllColumns = $true
        }
    }
    foreach($columnSchema in $tableSchema.Columns)
    {
        $fullColumnName = $tableSchema.QuotedName + "." + $columnSchema.QuotedName
        if ($addAllColumns -or $MetadataList.Contains($fullColumnName))
        {
            if ((-not $addAllColumns) -and $tableSchema.HasError)
            {
                Write-Host "Can't add column $fullColumnName to the sync schema" -foregroundcolor "Red"
                Write-Host $tableSchema.ErrorId -foregroundcolor "Red"c            }
            elseif ((-not $addAllColumns) -and $columnSchema.HasError)
            {
                Write-Host "Can't add column $fullColumnName to the sync schema" -foregroundcolor "Red"
                Write-Host $columnSchema.ErrorId -foregroundcolor "Red"
            }
            else
            {
                Write-Host "Adding"$fullColumnName" to the sync schema"
                $newColumnSchema = [AzureSqlSyncGroupSchemaColumnModel]::new()
                $newColumnSchema.QuotedName = $columnSchema.QuotedName
                $newColumnSchema.DataSize = $columnSchema.DataSize
                $newColumnSchema.DataType = $columnSchema.DataType
                $newTableSchema.Columns.Add($newColumnSchema)
            }
        }
    }
    if ($newTableSchema.Columns.Count -gt 0)
    {
        $newSchema.Tables.Add($newTableSchema)
    }
}

# Convert sync schema to Json format
$schemaString = $newSchema | ConvertTo-Json -depth 5 -Compress

# workaround a powershell bug
$schemaString = $schemaString.Replace('"Tables"', '"tables"').Replace('"Columns"', '"columns"').Replace('"QuotedName"', '"quotedName"').Replace('"MasterSyncMemberName"','"masterSyncMemberName"')

# Save the sync schema to a temp file
$schemaString | Out-File $TempFile

# Update sync schema
Write-Host "Updating the sync schema"
Update-AzSqlSyncGroup  -ResourceGroupName $ResourceGroupName `
                            -ServerName $ServerName `
                            -DatabaseName $DatabaseName `
                            -Name $SyncGroupName `
                            -Schema $TempFile

$SyncLogStartTime = Get-Date

# Trigger sync manually
Write-Host "Trigger sync manually"
Start-AzSqlSyncGroupSync  -ResourceGroupName $ResourceGroupName `
                               -ServerName $ServerName `
                               -DatabaseName $DatabaseName `
                               -SyncGroupName $SyncGroupName

# Check the sync log and wait until the first sync succeeded
Write-Host "Check the sync log"
$IsSucceeded = $false
For ($i = 0; ($i -lt 300) -and (-not $IsSucceeded); $i = $i + 10)
{
    Start-Sleep -s 10
    $SyncLogEndTime = Get-Date
    $SyncLogList = Get-AzSqlSyncGroupLog  -ResourceGroupName $ResourceGroupName `
                                           -ServerName $ServerName `
                                           -DatabaseName $DatabaseName `
                                           -SyncGroupName $SyncGroupName `
                                           -StartTime $SyncLogStartTime.ToUniversalTime() `
                                           -EndTime $SyncLogEndTime.ToUniversalTime()
    if ($SynclogList.Length -gt 0)
    {
        foreach ($SyncLog in $SyncLogList)
        {
            if ($SyncLog.Details.Contains("Sync completed successfully"))
            {
                Write-Host $SyncLog.TimeStamp : $SyncLog.Details
                $IsSucceeded = $true
            }
        }
    }
}

if ($IsSucceeded)
{
    # Enable scheduled sync
    Write-Host "Enable the scheduled sync with 300 seconds interval"
    Update-AzSqlSyncGroup  -ResourceGroupName $ResourceGroupName `
                                -ServerName $ServerName `
                                -DatabaseName $DatabaseName `
                                -Name $SyncGroupName `
                                -IntervalInSeconds $IntervalInSeconds
}
else
{
    # Output all log if sync doesn't succeed in 300 seconds
    $SyncLogEndTime = Get-Date
    $SyncLogList = Get-AzSqlSyncGroupLog  -ResourceGroupName $ResourceGroupName `
                                           -ServerName $ServerName `
                                           -DatabaseName $DatabaseName `
                                           -SyncGroupName $SyncGroupName `
                                           -StartTime $SyncLogStartTime.ToUniversalTime() `
                                           -EndTime $SyncLogEndTime.ToUniversalTime()
    if ($SynclogList.Length -gt 0)
    {
        foreach ($SyncLog in $SyncLogList)
        {
            Write-Host $SyncLog.TimeStamp : $SyncLog.Details
        }
    }
}

# Clean up deployment 
# Remove-AzResourceGroup -ResourceGroupName $resourcegroupname
# Remove-AzResourceGroup -ResourceGroupName $SyncDatabaseResourceGroupName

Limpar a implantaçãoClean up deployment

Após a execução do exemplo de script, execute o comando a seguir para remover o grupo de recursos e todos os recursos associados a ele.After you run the sample script, you can run the following command to remove the resource group and all resources associated with it.

Remove-AzResourceGroup -ResourceGroupName $ResourceGroupName
Remove-AzResourceGroup -ResourceGroupName $SyncDatabaseResourceGroupName

Explicação sobre o scriptScript explanation

Este script usa os comandos a seguir.This script uses the following commands. Cada comando na tabela redireciona para a documentação específica do comando.Each command in the table links to command-specific documentation.

ComandoCommand ObservaçõesNotes
New-AzSqlSyncAgentNew-AzSqlSyncAgent Cria um novo Agente de SincronizaçãoCreates a new Sync Agent
New-AzSqlSyncAgentKeyNew-AzSqlSyncAgentKey Gera a chave do agente associada ao Agente de sincronizaçãoGenerates the agent key associated with the Sync agent
Get-AzSqlSyncAgentLinkedDatabaseGet-AzSqlSyncAgentLinkedDatabase Obtém todas as informações para o Agente de SincronizaçãoGet all the information for the Sync Agent
New-AzSqlSyncMemberNew-AzSqlSyncMember Adiciona um novo membro ao Grupo de SincronizaçãoAdd a new member to the Sync Group
Update-AzSqlSyncSchemaUpdate-AzSqlSyncSchema Atualiza as informações de esquema de banco de dadosRefreshes the database schema information
Get-AzSqlSyncSchemaGet-AzSqlSyncSchema Obtém as informações de esquema de banco de dadosGet the database schema information
Update-AzSqlSyncGroupUpdate-AzSqlSyncGroup Atualiza o Grupo de SincronizaçãoUpdates the Sync Group
Start-AzSqlSyncGroupSyncStart-AzSqlSyncGroupSync Dispara uma SincronizaçãoTriggers a Sync
Get-AzSqlSyncGroupLogGet-AzSqlSyncGroupLog Verifica o Log de SincronizaçãoChecks the Sync Log

Próximas etapasNext steps

Para saber mais sobre o Azure PowerShell, confira Documentação do Azure PowerShell.For more information about Azure PowerShell, see Azure PowerShell documentation.

Os exemplos de script do PowerShell do Banco de Dados SQL adicionais podem ser encontrados nos scripts do PowerShell do Banco de Dados SQL do Azure.Additional SQL Database PowerShell script samples can be found in Azure SQL Database PowerShell scripts.

Para saber mais sobre a Sincronização de Dados SQL, veja:For more info about SQL Data Sync, see:

Para saber mais sobre o Banco de Dados SQL, veja:For more info about SQL Database, see: