Eseguire la migrazione di MySQL a Database di Azure per MySQL offline con PowerShell e Servizio Migrazione del database di Azure

In questo articolo si esegue la migrazione di un database MySQL ripristinato in un'istanza locale per Database di Azure per MySQL usando la funzionalità di migrazione offline di Servizio Migrazione del database di Azure tramite Microsoft Azure PowerShell. L'articolo illustra una raccolta di script di PowerShell che possono essere eseguiti in sequenza per eseguire la migrazione offline del database MySQL ad Azure. È possibile scaricare lo script di PowerShell completo descritto in questa esercitazione dal repository GitHub.

Nota

Attualmente non è possibile eseguire la migrazione completa del database usando il modulo Az.DataMigration. Nel frattempo, lo script di PowerShell di esempio viene fornito "così com'è" che usa l'API REST dms e consente di automatizzare la migrazione. Questo script verrà modificato o deprecato, una volta aggiunto il supporto ufficiale nel modulo Az.DataMigration e nell'interfaccia della riga di comando di Azure.

Nota

Amazon Relational Database Service (RDS) per MySQL e Amazon Aurora (basato su MySQL) sono supportati anche come origini per la migrazione.

Importante

Per le migrazioni online, è possibile usare strumenti open source come MyDumper/MyLoader con la replica dei dati in ingresso.

L'articolo consente di automatizzare lo scenario in cui i nomi di database di origine e di destinazione possono essere uguali o diversi e, come parte della migrazione, è necessario eseguire la migrazione di tutte o poche tabelle nel database di destinazione con lo stesso nome e struttura di tabella. Sebbene gli articoli presuppongono che l'origine sia un'istanza del database MySQL e che sia una destinazione da Database di Azure per MySQL, può essere usata per eseguire la migrazione da una Database di Azure per MySQL a un'altra semplicemente modificando il nome e le credenziali del server di origine. Inoltre, è supportata anche la migrazione dai server MySQL versione inferiore (v5.6 e versioni successive) alle versioni successive.

Importante

Le funzionalità di anteprima del Servizio Migrazione del database sono disponibili in modalità self-service, consenso esplicito. Le anteprime vengono fornite "così com'è" e "come disponibili" e vengono escluse dai contratti di servizio e dalla garanzia limitata. Di conseguenza, queste funzionalità non sono destinate all'uso in produzione. Per altre informazioni, vedere le Condizioni supplementari per l'uso delle anteprime di Microsoft Azure.

In questo articolo vengono illustrate le operazioni seguenti:

  • Eseguire la migrazione dello schema del database.
  • Crea un gruppo di risorse.
  • Creare un'istanza del Servizio Migrazione del database di Azure.
  • Creare un progetto di migrazione in un'istanza del Servizio Migrazione del database di Azure.
  • Configurare il progetto di migrazione per usare la funzionalità di migrazione offline per MySQL.
  • Eseguire la migrazione.

Prerequisiti

Per completare questi passaggi è necessario disporre di:

  • Avere a disposizione un account Azure con una sottoscrizione attiva. Creare un account gratuitamente.

  • Disporre di un database MySQL locale con la versione 5.6 o successiva. In caso contrario, scaricare e installare MySQL Community Edition 5.6 o versione successiva.

  • Creare un'istanza in Database di Azure per MySQL. Vedere l'articolo Usare MySQL Workbench per connettersi ed eseguire query sui dati per informazioni dettagliate su come connettersi e creare un database usando l'applicazione Workbench. La versione Database di Azure per MySQL deve essere uguale o successiva a quella di MySQL locale. Ad esempio, MySQL 5.7 può eseguire la migrazione a Database di Azure per MySQL 5.7 o aggiornata a 8.

  • Creare una rete virtuale di Microsoft Azure per il Servizio Migrazione del database di Azure usando il modello di distribuzione Azure Resource Manager, che offre la connettività da sito a sito per i server di origine locali con ExpressRoute o VPN. Per altre informazioni sulla creazione di una rete virtuale, vedere la documentazione sulla rete virtuale e in particolare gli articoli di avvio rapido con istruzioni dettagliate.

    Nota

    Durante la configurazione della rete virtuale, se si usa ExpressRoute con peering di rete a Microsoft, aggiungere l'endpoint del servizio Microsoft.Sql alla subnet in cui verrà effettuato il provisioning del servizio. Questa configurazione è necessaria perché il Servizio Migrazione del database di Azure non ha connettività Internet.

  • Assicurarsi che le regole del gruppo di sicurezza di rete virtuale non blocchino la porta in uscita 443 di ServiceTag per Archiviazione e AzureMonitor. Per informazioni dettagliate sul filtro del traffico dei gruppi di sicurezza di rete della rete virtuale di Azure, vedere l'articolo Filtrare il traffico di rete con gruppi di sicurezza di rete.

  • Aprire Windows Firewall per consentire le connessioni da Rete virtuale per Servizio Migrazione del database di Azure di accedere al server MySQL di origine, che per impostazione predefinita è la porta TCP 3306.

  • Quando si usa un'appliance firewall davanti ai database di origine, potrebbe essere necessario aggiungere regole del firewall per consentire alle connessioni da Rete virtuale per Servizio Migrazione del database di Azure di accedere ai database di origine per la migrazione.

  • Creare una regola del firewall a livello di server o configurare gli endpoint servizio di rete virtuale per le Database di Azure per MySQL di destinazione per consentire Rete virtuale per Servizio Migrazione del database di Azure l'accesso ai database di destinazione.

  • L'origine MySQL deve essere in un'Edizione MySQL Community supportata. Per determinare la versione dell'istanza di MySQL, eseguire il comando seguente nell'utilità MySQL o in MySQL Workbench:

    SELECT @@version;
    
  • Database di Azure per MySQL supporta solo le tabelle InnoDB. Per convertire le tabelle MyISAM in InnoDB, vedere l'articolo Converting Tables from MyISAM to InnoDB (Conversione di tabelle da MyISAM a InnoDB).

  • L'utente deve disporre dei privilegi per leggere i dati nel database di origine.

  • La guida usa PowerShell v7.2, che può essere installato in base alla guida all'installazione

  • Scaricare e installare i moduli seguenti da PowerShell Gallery usando il cmdlet di PowerShell Install-Module. Assicurarsi di aprire la finestra di comando di PowerShell usando l'esecuzione come Amministrazione istrator:

    • Az.Resources
    • Az.Network
    • Az.DataMigration
Install-Module Az.Resources
Install-Module Az.Network
Install-Module Az.DataMigration
Import-Module Az.Resources
Import-Module Az.Network
Import-Module Az.DataMigration

Eseguire la migrazione dello schema del database

Per trasferire tutti gli oggetti di database come schemi di tabella, indici e stored procedure, è necessario estrarre lo schema dal database di origine e applicarli al database di destinazione. Per estrarre lo schema, è possibile usare mysqldump con il parametro --no-data. Per questo è necessario un computer in grado di connettersi sia al database MySQL di origine che al Database di Azure per MySQL di destinazione.

Per esportare lo schema usando mysqldump, eseguire il comando seguente:

mysqldump -h [servername] -u [username] -p[password] --databases [db name] --no-data > [schema file path]

Ad esempio:

mysqldump -h 10.10.123.123 -u root -p --databases migtestdb --no-data > d:\migtestdb.sql

Per importare lo schema nel Database di Azure per MySQL di destinazione, eseguire il comando seguente:

mysql.exe -h [servername] -u [username] -p[password] [database]< [schema file path]

Ad esempio:

mysql.exe -h mysqlsstrgt.mysql.database.azure.com -u docadmin@mysqlsstrgt -p migtestdb < d:\migtestdb.sql

Se si dispone di chiavi esterne nello schema, il caricamento parallelo dei dati durante la migrazione verrà gestito dall'attività di migrazione. Non è necessario eliminare chiavi esterne durante la migrazione dello schema.

Se nel database sono presenti trigger, l'integrità dei dati verrà applicata nella destinazione prima della migrazione completa dei dati dall'origine. È consigliabile disabilitare i trigger in tutte le tabelle nella destinazione durante la migrazione e quindi abilitare i trigger al termine della migrazione.

Eseguire lo script seguente in MySQL Workbench nel database di destinazione per estrarre lo script di rilascio del trigger e aggiungere lo script trigger.

SELECT
    SchemaName,
    GROUP_CONCAT(DropQuery SEPARATOR ';\n') as DropQuery,
    Concat('DELIMITER $$ \n\n', GROUP_CONCAT(AddQuery SEPARATOR '$$\n'), '$$\n\nDELIMITER ;') as AddQuery
FROM
(
SELECT
    TRIGGER_SCHEMA as SchemaName,
    Concat('DROP TRIGGER `', TRIGGER_NAME, "`") as DropQuery,
    Concat('CREATE TRIGGER `', TRIGGER_NAME, '` ', ACTION_TIMING, ' ', EVENT_MANIPULATION,
            '\nON `', EVENT_OBJECT_TABLE, '`\n' , 'FOR EACH ', ACTION_ORIENTATION, ' ',
            ACTION_STATEMENT) as AddQuery
FROM
    INFORMATION_SCHEMA.TRIGGERS
ORDER BY EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, ACTION_TIMING, EVENT_MANIPULATION, ACTION_ORDER ASC
) AS Queries
GROUP BY SchemaName

Eseguire la query di rilascio generata (colonna DropQuery) nel risultato per eliminare i trigger nel database di destinazione. È possibile salvare la query di aggiunta del trigger da usare dopo il completamento della migrazione dei dati.

Accedere alla sottoscrizione di Microsoft Azure

Usare il comando powerShell Connessione-AzAccount per accedere alla sottoscrizione di Azure usando PowerShell, come indicato nell'articolo Accedere con Azure PowerShell.

Lo script seguente imposta la sottoscrizione predefinita per l'accesso post-accesso della sessione di PowerShell e crea una funzione di registrazione helper per i log della console formattati.

[string] $SubscriptionName = "mySubscription"
$ErrorActionPreference = "Stop";

Connect-AzAccount
Set-AzContext -Subscription $SubscriptionName
$global:currentSubscriptionId = (Get-AzContext).Subscription.Id;

function LogMessage([string] $Message, [bool] $IsProcessing = $false) {
    if ($IsProcessing) {
        Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss"): $Message" -ForegroundColor Yellow
    }
    else {
        Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss"): $Message" -ForegroundColor Green
    }
}

Registrare il provider di risorse Microsoft.DataMigration

La registrazione del provider di risorse deve essere eseguita in ogni sottoscrizione di Azure una sola volta. Senza la registrazione, non sarà possibile creare un'istanza di Servizio Migrazione del database di Azure.

Registrare il provider di risorse usando il comando Register-AzResourceProvider . Lo script seguente registra il provider di risorse necessario per Servizio Migrazione del database di Azure

Register-AzResourceProvider -ProviderNamespace Microsoft.DataMigration

Creare un gruppo di risorse

Un gruppo di risorse di Azure è un contenitore logico in cui le risorse di Azure vengono distribuite e gestite. Creare un gruppo di risorse prima di creare tutte le risorse del Servizio Migrazione del database.

Creare un gruppo di risorse usando il comando New-AzResourceGroup .

L'esempio seguente crea un gruppo di risorse denominato myResourceGroup nell'area Stati Uniti occidentali 2 nella sottoscrizione predefinita mySubscription.

# Get the details of resource group
[string] $Location = "westus2"
[string] $ResourceGroupName = "myResourceGroup"

$resourceGroup = Get-AzResourceGroup -Name $ResourceGroupName
if (-not($resourceGroup)) {
    LogMessage -Message "Creating resource group $ResourceGroupName..." -IsProcessing $true
    $resourceGroup = New-AzResourceGroup -Name $ResourceGroupName -Location $Location
    LogMessage -Message "Created resource group - $($resourceGroup.ResourceId)."
}
else { LogMessage -Message "Resource group $ResourceGroupName exists." }

Creare un'istanza del Servizio Migrazione del database di Azure

È possibile creare una nuova istanza di Servizio Migrazione del database di Azure usando il comando New-AzDataMigrationService. Questo comando prevede i parametri obbligatori seguenti:

  • Nome del gruppo di risorse di Azure. È possibile usare il comando New-AzResourceGroup per creare un gruppo di risorse di Azure come illustrato in precedenza e specificarne il nome come parametro.
  • Nome del servizio. Stringa che corrisponde al nome di servizio univoco desiderato per il Servizio Migrazione del database di Azure
  • Posizione. Specifica il percorso del servizio. Specificare un percorso di data center di Azure, ad esempio Stati Uniti occidentali o Asia sud-orientale
  • Sku. Questo parametro corrisponde al nome Sku DMS. Il nome sku attualmente supportato è Standard_1vCore, Standard_2vCores, Standard_4vCores Premium_4vCores.
  • Identificatore della subnet virtuale. È possibile usare il comando Get-AzVirtualNetworkSubnetConfig per ottenere le informazioni di una subnet.

Lo script seguente prevede che la rete virtuale myVirtualNetwork esista con una subnet denominata default e quindi crea un Servizio Migrazione del database con il nome myDmService nel gruppo di risorse creato nel passaggio 3 e nella stessa area.

# Get a reference to the DMS service - Create if not exists
[string] $VirtualNetworkName = "myVirtualNetwork"
[string] $SubnetName = "default"
[string] $ServiceName = "myDmService"

$dmsServiceResourceId = "/subscriptions/$($global:currentSubscriptionId)/resourceGroups/$ResourceGroupName/providers/Microsoft.DataMigration/services/$ServiceName"
$dmsService = Get-AzResource -ResourceId $dmsServiceResourceId -ErrorAction SilentlyContinue

# Create Azure DMS service if not existing
# Possible values for SKU currently are Standard_1vCore,Standard_2vCores,Standard_4vCores,Premium_4vCores
if (-not($dmsService)) {
    $virtualNetwork = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName -Name $VirtualNetworkName
    if (-not ($virtualNetwork)) { throw "ERROR: Virtual Network $VirtualNetworkName does not exists" }

    $subnet = Get-AzVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetwork -Name $SubnetName
    if (-not ($subnet)) { throw "ERROR: Virtual Network $VirtualNetworkName does not contains Subnet $SubnetName" }

    LogMessage -Message "Creating Azure Data Migration Service $ServiceName..." -IsProcessing $true
    $dmsService = New-AzDataMigrationService `
        -ResourceGroupName $ResourceGroupName `
        -Name $ServiceName `
        -Location $resourceGroup.Location `
        -Sku Premium_4vCores `
        -VirtualSubnetId $Subnet.Id

    $dmsService = Get-AzResource -ResourceId $dmsServiceResourceId
    LogMessage -Message "Created Azure Data Migration Service - $($dmsService.ResourceId)."
}
else { LogMessage -Message "Azure Data Migration Service $ServiceName exists." }

Creare un progetto di migrazione

Dopo aver creato un'istanza di Servizio Migrazione del database di Azure, si creerà un progetto di migrazione. Un progetto di migrazione specifica il tipo di migrazione da eseguire.

Lo script seguente crea un progetto di migrazione denominato myfirstmysqlofflineproject per la migrazione offline da MySQL a Database di Azure per MySQL nell'istanza di Servizio Migrazione del database creata nel passaggio 4 e nella stessa area.

# Get a reference to the DMS project - Create if not exists
[string] $ProjectName = "myfirstmysqlofflineproject"

$dmsProjectResourceId = "/subscriptions/$($global:currentSubscriptionId)/resourceGroups/$($dmsService.ResourceGroupName)/providers/Microsoft.DataMigration/services/$($dmsService.Name)/projects/$projectName"
$dmsProject = Get-AzResource -ResourceId $dmsProjectResourceId -ErrorAction SilentlyContinue

# Create Azure DMS Project if not existing
if (-not($dmsProject)) {
    LogMessage -Message "Creating Azure DMS project $projectName for MySQL migration ..." -IsProcessing $true

    $newProjectProperties = @{"sourcePlatform" = "MySQL"; "targetPlatform" = "AzureDbForMySQL" }
    $dmsProject = New-AzResource `
        -ApiVersion 2018-03-31-preview `
        -Location $dmsService.Location `
        -ResourceId $dmsProjectResourceId `
        -Properties $newProjectProperties `
        -Force

    LogMessage -Message "Created Azure DMS project $projectName - $($dmsProject.ResourceId)."
}
else { LogMessage -Message "Azure DMS project $projectName exists." }

Creare un oggetto informazioni di connessione del database per le connessioni di origine e di destinazione

Dopo aver creato il progetto di migrazione, verranno create le informazioni di connessione al database. Queste informazioni di connessione verranno usate per connettersi ai server di origine e di destinazione durante il processo di migrazione.

Lo script seguente accetta il nome del server, il nome utente e la password per le istanze mySQL di origine e destinazione e crea gli oggetti informazioni di connessione. Lo script richiede all'utente di immettere la password per le istanze mySQL di origine e di destinazione. Per gli script invisibile all'utente, le credenziali possono essere recuperate da Azure Key Vault.

# Initialize the source and target database server connections
[string] $SourceServerName = "13.66.136.192"
[string] $SourceUserName = "docadmin@mysqlserver"
[securestring] $SourcePassword = Read-Host "Enter MySQL Source Server Password" -AsSecureString

[string] $TargetServerName = "migdocdevwus2mysqlsstrgt.mysql.database.azure.com"
[string] $TargetUserName = "docadmin@migdocdevwus2mysqlsstrgt"
[securestring] $TargetPassword = Read-Host "Enter MySQL Target Server Password" -AsSecureString

function InitConnection(
    [string] $ServerName,
    [string] $UserName,
    [securestring] $Password) {
    $connectionInfo = @{
        "dataSource"             = "";
        "serverName"             = "";
        "port"                   = 3306;
        "userName"               = "";
        "password"               = "";
        "authentication"         = "SqlAuthentication";
        "encryptConnection"      = $true;
        "trustServerCertificate" = $true;
        "additionalSettings"     = "";
        "type"                   = "MySqlConnectionInfo"
    }

    $connectionInfo.dataSource = $ServerName;
    $connectionInfo.serverName = $ServerName;
    $connectionInfo.userName = $UserName;
    $connectionInfo.password = (ConvertFrom-SecureString -AsPlainText $password).ToString();
    $connectionInfo;
}

# Initialize the source and target connections
LogMessage -Message "Initializing source and target connection objects ..." -IsProcessing $true
$sourceConnInfo = InitConnection `
    $SourceServerName `
    $SourceUserName `
    $SourcePassword;

$targetConnInfo = InitConnection `
    $TargetServerName `
    $TargetUserName `
    $TargetPassword;

LogMessage -Message "Source and target connection object initialization complete."

Estrarre l'elenco di nomi di tabella dal database di destinazione

L'elenco di tabelle di database può essere estratto usando un'attività di migrazione e informazioni di connessione. L'elenco di tabelle verrà estratto sia dal database di origine che dal database di destinazione in modo che sia possibile eseguire il mapping e la convalida appropriati.

Lo script seguente accetta i nomi dei database di origine e di destinazione e quindi estrae l'elenco di tabelle dai database usando l'attività di migrazione GetUserTablesMySql .

# Run scenario to get the tables from the target database to build
# the migration table mapping
[string] $TargetDatabaseName = "migtargetdb"
[string] $SourceDatabaseName = "migsourcedb"

function RunScenario([object] $MigrationService,
    [object] $MigrationProject,
    [string] $ScenarioTaskName,
    [object] $TaskProperties,
    [bool] $WaitForScenario = $true) {
    # Check if the scenario task already exists, if so remove it
    LogMessage -Message "Removing scenario if already exists..." -IsProcessing $true
    Remove-AzDataMigrationTask `
        -ResourceGroupName $MigrationService.ResourceGroupName `
        -ServiceName $MigrationService.Name `
        -ProjectName $MigrationProject.Name `
        -TaskName $ScenarioTaskName `
        -Force;

    # Start the new scenario task using the provided properties
    LogMessage -Message "Initializing scenario..." -IsProcessing $true
    New-AzResource `
        -ApiVersion 2018-03-31-preview `
        -Location $MigrationService.Location `
        -ResourceId "/subscriptions/$($global:currentSubscriptionId)/resourceGroups/$($MigrationService.ResourceGroupName)/providers/Microsoft.DataMigration/services/$($MigrationService.Name)/projects/$($MigrationProject.Name)/tasks/$($ScenarioTaskName)" `
        -Properties $TaskProperties `
        -Force | Out-Null;

    LogMessage -Message "Waiting for $ScenarioTaskName scenario to complete..." -IsProcessing $true
    if ($WaitForScenario) {
        $progressCounter = 0;
        do {
            if ($null -ne $scenarioTask) {
                Start-Sleep 10;
            }

            # Get calls can time out and will return a cancellation exception in that case
            $scenarioTask = Get-AzDataMigrationTask `
                -ResourceGroupName $MigrationService.ResourceGroupName `
                -ServiceName $MigrationService.Name `
                -ProjectName $MigrationProject.Name `
                -TaskName $ScenarioTaskName `
                -Expand `
                -ErrorAction Ignore;

            Write-Progress -Activity "Scenario Run $ScenarioTaskName  (Marquee Progress Bar)" `
                -Status $scenarioTask.ProjectTask.Properties.State `
                -PercentComplete $progressCounter

            $progressCounter += 10;
            if ($progressCounter -gt 100) { $progressCounter = 10 }
        }
        while (($null -eq $scenarioTask) -or ($scenarioTask.ProjectTask.Properties.State -eq "Running") -or ($scenarioTask.ProjectTask.Properties.State -eq "Queued"))
    }
    Write-Progress -Activity "Scenario Run $ScenarioTaskName" `
        -Status $scenarioTask.ProjectTask.Properties.State `
        -Completed

    # Now get it using REST APIs so we can expand the output
    LogMessage -Message "Getting expanded task results ..." -IsProcessing $true
    $psToken = (Get-AzAccessToken -ResourceUrl https://management.azure.com).Token;
    $token = ConvertTo-SecureString -String $psToken -AsPlainText -Force;
    $taskResource = Invoke-RestMethod `
        -Method GET `
        -Uri "https://management.azure.com$($scenarioTask.ProjectTask.Id)?api-version=2018-03-31-preview&`$expand=output" `
        -ContentType "application/json" `
        -Authentication Bearer `
        -Token $token;

    $taskResource.properties;
}

# create the get table task properties by initializing the connection and
# database name
$getTablesTaskProperties = @{
    "input"    = @{
        "connectionInfo"    = $null;
        "selectedDatabases" = $null;
    };
    "taskType" = "GetUserTablesMySql";
};

LogMessage -Message "Running scenario to get the list of tables from the target database..." -IsProcessing $true
$getTablesTaskProperties.input.connectionInfo = $targetConnInfo;
$getTablesTaskProperties.input.selectedDatabases = @($TargetDatabaseName);
# Create a name for the task
$getTableTaskName = "$($TargetDatabaseName)GetUserTables"
# Get the list of tables from the source
$getTargetTablesTask = RunScenario -MigrationService $dmsService `
    -MigrationProject $dmsProject `
    -ScenarioTaskName $getTableTaskName `
    -TaskProperties $getTablesTaskProperties;

if (-not ($getTargetTablesTask)) { throw "ERROR: Could not get target database $TargetDatabaseName table information." }
LogMessage -Message "List of tables from the target database acquired."

LogMessage -Message "Running scenario to get the list of tables from the source database..." -IsProcessing $true
$getTablesTaskProperties.input.connectionInfo = $sourceConnInfo;
$getTablesTaskProperties.input.selectedDatabases = @($SourceDatabaseName);
# Create a name for the task
$getTableTaskName = "$($SourceDatabaseName)GetUserTables"
# Get the list of tables from the source
$getSourceTablesTask = RunScenario -MigrationService $dmsService `
    -MigrationProject $dmsProject `
    -ScenarioTaskName $getTableTaskName `
    -TaskProperties $getTablesTaskProperties;

if (-not ($getSourceTablesTask)) { throw "ERROR: Could not get source database $SourceDatabaseName table information." }
LogMessage -Message "List of tables from the source database acquired."

Creare il mapping delle tabelle in base alla configurazione utente

Durante la configurazione dell'attività di migrazione, si creerà un mapping tra le tabelle di origine e di destinazione. Il mapping è a livello di nome tabella, ma si presuppone che la struttura della tabella (numero di colonne, nomi di colonna, tipi di dati e così via) delle tabelle mappate sia esattamente la stessa.

Lo script seguente crea un mapping basato sull'elenco di tabelle di destinazione e di origine estratto nel passaggio 7. Per il caricamento parziale dei dati, l'utente può fornire un elenco di tabelle per filtrare le tabelle. Se non viene fornito alcun input utente, viene eseguito il mapping di tutte le tabelle di destinazione. Lo script controlla anche se nell'origine esiste o meno una tabella con lo stesso nome. Se il nome della tabella non esiste nell'origine, la tabella di destinazione viene ignorata per la migrazione.

# Create the source to target table map
# Optional table settings
# DEFAULT: $IncludeTables = $null => include all tables for migration
# DEFAULT: $ExcludeTables = $null => exclude no tables from migration
# Exclude list has higher priority than include list
# Array of qualified source table names which should be migrated
[string[]] $IncludeTables = @("migsourcedb.coupons", "migsourcedb.daily_cash_sheets");
[string[]] $ExcludeTables = $null;

LogMessage -Message "Creating the table map based on the user input and database table information ..." `
    -IsProcessing $true

$targetTables = $getTargetTablesTask.Output.DatabasesToTables."$TargetDatabaseName";
$sourceTables = $getSourceTablesTask.Output.DatabasesToTables."$SourceDatabaseName";
$tableMap = New-Object 'system.collections.generic.dictionary[string,string]';

$schemaPrefixLength = $($SourceDatabaseName + ".").Length;
$tableMappingError = $false
foreach ($srcTable in $sourceTables) {
    # Removing the database name prefix from the table name so that comparison
    # can be done in cases where database name given are different
    $tableName = $srcTable.Name.Substring($schemaPrefixLength, `
            $srcTable.Name.Length - $schemaPrefixLength)

    # In case the table is part of exclusion list then ignore the table
    if ($null -ne $ExcludeTables -and $ExcludeTables -contains $srcTable.Name) {
        continue;
    }

    # Either the include list is null or the table is part of the include list then add it in the mapping
    if ($null -eq $IncludeTables -or $IncludeTables -contains $srcTable.Name) {
        # Check if the table exists in the target. If not then log TABLE MAPPING ERROR
        if (-not ($targetTables | Where-Object { $_.name -ieq "$($TargetDatabaseName).$tableName" })) {
            $tableMappingError = $true
            Write-Host "TABLE MAPPING ERROR: $($targetTables.name) does not exists in target." -ForegroundColor Red
            continue;
        }

        $tableMap.Add("$($SourceDatabaseName).$tableName", "$($TargetDatabaseName).$tableName");
    }
}

# In case of any table mapping errors identified, throw an error and stop the process
if ($tableMappingError) { throw "ERROR: One or more table mapping errors were identified. Please see previous messages." }
# In case no tables are in the mapping then throw error
if ($tableMap.Count -le 0) { throw "ERROR: Could not create table mapping." }
LogMessage -Message "Migration table mapping created for $($tableMap.Count) tables."

Creare e configurare gli input dell'attività di migrazione

Dopo aver compilato il mapping della tabella, si creeranno gli input per l'attività di migrazione di tipo Migrate.MySql.AzureDbForMySql e si configureranno le proprietà.

Lo script seguente crea l'attività di migrazione e imposta le connessioni, i nomi di database e il mapping delle tabelle.

# Create and configure the migration scenario based on the connections
# and the table mapping
$offlineMigTaskProperties = @{
    "input"    = @{
        "sourceConnectionInfo"  = $null;
        "targetConnectionInfo"  = $null;
        "selectedDatabases"     = $null;
        "optionalAgentSettings" = @{
            "EnableCacheBatchesInMemory"         = $true;
            "DisableIncrementalRowStatusUpdates" = $true;
        };
        "startedOn"             = $null;
    };
    "taskType" = "Migrate.MySql.AzureDbForMySql";
};
$offlineSelectedDatabase = @{
    "name"               = $null;
    "targetDatabaseName" = $null;
    "tableMap"           = $null;
};

LogMessage -Message "Preparing migration scenario configuration ..." -IsProcessing $true

# Select the database to be migrated
$offlineSelectedDatabase.name = $SourceDatabaseName;
$offlineSelectedDatabase.tableMap = New-Object PSObject -Property $tableMap;
$offlineSelectedDatabase.targetDatabaseName = $TargetDatabaseName;

# Set connection info and the database mapping
$offlineMigTaskProperties.input.sourceConnectionInfo = $sourceConnInfo;
$offlineMigTaskProperties.input.targetConnectionInfo = $targetConnInfo;
$offlineMigTaskProperties.input.selectedDatabases = @($offlineSelectedDatabase);
$offlineMigTaskProperties.input.startedOn = [System.DateTimeOffset]::UtcNow.ToString("O");

Configurare i parametri di ottimizzazione delle prestazioni

Come pert del modulo di PowerShell, sono disponibili alcuni parametri facoltativi, che possono essere ottimizzati in base all'ambiente. Questi parametri possono essere usati per migliorare le prestazioni dell'attività di migrazione. Tutti questi parametri sono facoltativi e il relativo valore predefinito è NULL.

Nota

Le configurazioni delle prestazioni seguenti hanno mostrato una maggiore velocità effettiva durante la migrazione nello SKU Premium.

  • WriteDataRangeBatchTaskCount = 12
  • DelayProgress Aggiornamenti In Archiviazione Interval = 30 secondi
  • ThrottleQueryTableDataRangeTaskAtBatchCount = 36

Lo script seguente accetta i valori utente dei parametri e imposta i parametri nelle proprietà dell'attività di migrazione.

# Setting optional parameters from fine tuning the data transfer rate during migration
# DEFAULT values for all the configurations is $null
LogMessage -Message "Adding optional migration performance tuning configuration ..." -IsProcessing $true
# Partitioning settings
# Optional setting that configures the maximum number of parallel reads on tables located on the source database.
[object] $DesiredRangesCount = 4
# Optional setting that configures that size of the largest batch that will be committed to the target server.
[object] $MaxBatchSizeKb = 4096
# Optional setting that configures the minimum number of rows in each batch written to the target.
[object] $MinBatchRows = $null
# Task count settings
# Optional setting that configures the number of databases that will be prepared for migration in parallel.
[object] $PrepareDatabaseForBulkImportTaskCount = $null
# Optional setting that configures the number of tables that will be prepared for migration in parallel.
[object] $PrepareTableForBulkImportTaskCount = $null
# Optional setting that configures the number of threads available to read ranges on the source.
[object] $QueryTableDataRangeTaskCount = 8
# Optional setting that configures the number of threads available to write batches to the target.
[object] $WriteDataRangeBatchTaskCount = 12
# Batch cache settings
# Optional setting that configures how much memory will be used to cache batches in memory before reads on the source are throttled.
[object] $MaxBatchCacheSizeMb = $null
# Optional setting that configures the amount of available memory at which point reads on the source will be throttled.
[object] $ThrottleQueryTableDataRangeTaskAtAvailableMemoryMb = $null
# Optional setting that configures the number of batches cached in memory that will trigger read throttling on the source.
[object] $ThrottleQueryTableDataRangeTaskAtBatchCount = 36
# Performance settings
# Optional setting that configures the delay between updates of result objects in Azure Table Storage.
[object] $DelayProgressUpdatesInStorageInterval = "00:00:30"

function AddOptionalSetting($optionalAgentSettings, $settingName, $settingValue) {
    # If no value specified for the setting, don't bother adding it to the input
    if ($null -eq $settingValue) {
        return;
    }

    # Add a new property to the JSON object to capture the setting which will be customized
    $optionalAgentSettings | add-member -MemberType NoteProperty -Name $settingName -Value $settingValue
}

# Set any optional settings in the input based on parameters to this cmdlet
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "DesiredRangesCount" $DesiredRangesCount;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "MaxBatchSizeKb" $MaxBatchSizeKb;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "MinBatchRows" $MinBatchRows;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "PrepareDatabaseForBulkImportTaskCount" $PrepareDatabaseForBulkImportTaskCount;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "PrepareTableForBulkImportTaskCount" $PrepareTableForBulkImportTaskCount;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "QueryTableDataRangeTaskCount" $QueryTableDataRangeTaskCount;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "WriteDataRangeBatchTaskCount" $WriteDataRangeBatchTaskCount;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "MaxBatchCacheSizeMb" $MaxBatchCacheSizeMb;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "ThrottleQueryTableDataRangeTaskAtAvailableMemoryMb" $ThrottleQueryTableDataRangeTaskAtAvailableMemoryMb;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "ThrottleQueryTableDataRangeTaskAtBatchCount" $ThrottleQueryTableDataRangeTaskAtBatchCount;
AddOptionalSetting $offlineMigTaskProperties.input.optionalAgentSettings "DelayProgressUpdatesInStorageInterval" $DelayProgressUpdatesInStorageInterval;

Creazione ed esecuzione dell'attività di migrazione

Dopo aver configurato l'input per l'attività, l'attività verrà creata ed eseguita nell'agente. Lo script attiva l'esecuzione dell'attività e attende il completamento della migrazione.

Lo script seguente richiama l'attività di migrazione configurata e attende il completamento.

# Running the migration scenario
[string] $TaskName = "mysqlofflinemigrate"

LogMessage -Message "Running data migration scenario ..." -IsProcessing $true
$summary = @{
    "SourceServer"   = $SourceServerName;
    "SourceDatabase" = $SourceDatabaseName;
    "TargetServer"   = $TargetServerName;
    "TargetDatabase" = $TargetDatabaseName;
    "TableCount"     = $tableMap.Count;
    "StartedOn"      = $offlineMigTaskProperties.input.startedOn;
}

Write-Host "Job Summary:" -ForegroundColor Yellow
Write-Host $(ConvertTo-Json $summary) -ForegroundColor Yellow

$migrationResult = RunScenario -MigrationService $dmsService `
    -MigrationProject $dmsProject `
    -ScenarioTaskName $TaskName `
    -TaskProperties $offlineMigTaskProperties

LogMessage -Message "Migration completed with status - $($migrationResult.state)"
#Checking for any errors or warnings captured by the task during migration
$dbLevelResult = $migrationResult.output | Where-Object { $_.resultType -eq "DatabaseLevelOutput" }
$migrationLevelResult = $migrationResult.output | Where-Object { $_.resultType -eq "MigrationLevelOutput" }
if ($dbLevelResult.exceptionsAndWarnings) {
    Write-Host "Following database errors were captured: $($dbLevelResult.exceptionsAndWarnings)" -ForegroundColor Red
}
if ($migrationLevelResult.exceptionsAndWarnings) {
    Write-Host "Following migration errors were captured: $($migrationLevelResult.exceptionsAndWarnings)" -ForegroundColor Red
}
if ($migrationResult.errors.details) {
    Write-Host "Following task level migration errors were captured: $($migrationResult.errors.details)" -ForegroundColor Red
}

Eliminazione del Servizio Migrazione del database

La stessa Servizio Migrazione del database può essere usata per più migrazioni in modo che l'istanza dopo la creazione possa essere riutilizzata. Se non si intende continuare a usare il Servizio Migrazione del database, è possibile eliminare il servizio usando il comando Remove-AzDataMigrationService.

Lo script seguente elimina l'istanza di Servizio Migrazione del database di Azure e i relativi progetti associati.

Remove-AzDataMigrationService -ResourceId $($dmsService.ResourceId)

Passaggi successivi