Dela via


Migrera MySQL till Azure Database for MySQL offline med PowerShell och Azure Database Migration Service

I den här artikeln migrerar du en MySQL-databas som återställts till en lokal instans till Azure Database for MySQL med hjälp av offlinemigreringsfunktionen i Azure Database Migration Service via Microsoft Azure PowerShell. Artikeln dokumenterar en samling PowerShell-skript som kan köras i följd för att utföra offlinemigreringen av MySQL-databasen till Azure. Du kan ladda ned det fullständiga PowerShell-skriptet som beskrivs i den här självstudien från vår GitHub-lagringsplats.

Kommentar

För närvarande går det inte att köra fullständig databasmigrering med hjälp av modulen Az.DataMigration. Under tiden tillhandahålls PowerShell-exempelskriptet "i den mån det är" som använder DMS REST-API:et och gör att du kan automatisera migreringen. Det här skriptet kommer att ändras eller bli inaktuellt när det officiella stödet har lagts till i Az.DataMigration-modulen och Azure CLI.

Amazon Relational Database Service (RDS) för MySQL och Amazon Aurora (MySQL-baserad) stöds också som källor för migrering.

Viktigt!

För onlinemigreringar kan du använda verktyg med öppen källkod, till exempel MyDumper/MyLoader med datareplikering.

Artikeln hjälper till att automatisera scenariot där käll- och måldatabasnamn kan vara samma eller olika och som en del av migreringen måste antingen alla eller få tabeller i måldatabasen migreras som har samma namn och tabellstruktur. Även om artiklarna förutsätter att källan är en MySQL-databasinstans och målet är Azure Database for MySQL, kan den användas för att migrera från en Azure Database for MySQL till en annan bara genom att ändra källserverns namn och autentiseringsuppgifter. Migrering från mySQL-servrar med lägre version (v5.6 och senare) till högre versioner stöds också.

Viktigt!

DMS-förhandsversionsfunktioner är tillgängliga via självbetjäning och anmäl dig. Förhandsversioner tillhandahålls "som är" och "som tillgängliga", och de undantas från serviceavtalen och den begränsade garantin. Därför är dessa funktioner inte avsedda för produktionsanvändning. Mer information finns i Kompletterande användningsvillkor för Förhandsversioner av Microsoft Azure.

I den här artikeln kan du se hur du:

  • Migrera databasschema.
  • Skapa en resursgrupp.
  • Skapa en instans av Azure Database Migration Service.
  • Skapa ett migreringsprojekt i en Azure Database Migration Service-instans.
  • Konfigurera migreringsprojektet för att använda offlinemigreringsfunktionen för MySQL.
  • Köra migreringen.

Förutsättningar

För att slutföra de här stegen behöver du:

  • Ha ett Azure-konto med en aktiv prenumeration. Skapa ett konto utan kostnad.

  • Ha en lokal MySQL-databas med version 5.6 eller senare. Annars laddar du ned och installerar MySQL Community Edition 5.6 eller senare.

  • Skapa en instans i Azure Database for MySQL. Mer information om hur du ansluter och skapar en databas med workbench-programmet finns i artikeln Använd MySQL Workbench för att ansluta och fråga efter data . Azure Database for MySQL-versionen ska vara lika med eller högre än den lokala MySQL-versionen . MySQL 5.7 kan till exempel migrera till Azure Database for MySQL 5.7 eller uppgraderas till 8.

  • Skapa ett Microsoft Azure Virtual Network for Azure Database Migration Service med hjälp av Azure Resource Manager-distributionsmodellen, som tillhandahåller plats-till-plats-anslutning till dina lokala källservrar med hjälp av antingen ExpressRoute eller VPN. Mer information om hur du skapar ett virtuellt nätverk finns i dokumentationen för virtuellt nätverk, och särskilt snabbstartsartiklarna med stegvis information.

    Kommentar

    Om du använder ExpressRoute med nätverkspeering till Microsoft under konfigurationen av virtuellt nätverk lägger du till tjänstslutpunkten Microsoft.Sql i det undernät där tjänsten ska etableras. Den här konfigurationen är nödvändig eftersom Azure Database Migration Service saknar Internetanslutning.

  • Se till att reglerna för nätverkssäkerhetsgruppen för det virtuella nätverket inte blockerar utgående port 443 i ServiceTag för Storage och AzureMonitor. Mer information om trafikfiltrering för virtuella nätverk NSG finns i artikeln Filtrera nätverkstrafik med nätverkssäkerhetsgrupper.

  • Öppna Windows-brandväggen för att tillåta anslutningar från Virtual Network for Azure Database Migration Service att komma åt källans MySQL-server, som som standard är TCP-port 3306.

  • När du använder en brandväggsinstallation framför källdatabaserna kan du behöva lägga till brandväggsregler för att tillåta anslutningar från Virtual Network för Azure Database Migration Service att komma åt källdatabaserna för migrering.

  • Skapa en brandväggsregel på servernivå eller konfigurera VNET-tjänstslutpunkter för Azure Database for MySQL som mål för att tillåta virtuellt nätverk för Azure Database Migration Service åtkomst till måldatabaserna.

  • MySQL-källan måste vara på en MySQL Community Edition som stöds. Om du vill kontrollera vilken version av MySQL-instansen du har går du till verktyget MySQL eller MySQL Workbench och kör följande kommando:

    SELECT @@VERSION;
    
  • Azure Database for MySQL stöder endast InnoDB-tabeller. Om du vill konvertera MyISAM-tabeller till InnoDB kan du läsa artikeln Konvertera tabeller från MyISAM till InnoDB

  • Användaren måste ha behörighet att läsa data i källdatabasen.

  • Guiden använder PowerShell v7.2, som kan installeras enligt installationsguiden

  • Ladda ned och installera följande moduler från PowerShell-galleriet med hjälp av PowerShell-cmdleten Install-Module. Öppna PowerShell-kommandofönstret med kör som administratör:

    • 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
    

Migrera databasschema

För att överföra alla databasobjekt som tabellscheman, index och lagrade procedurer måste vi extrahera schemat från källdatabasen och tillämpa på måldatabasen. Du kan extrahera schema med mysqldump med parametern --no-data. För detta behöver du en dator som kan ansluta till både MySQL-källdatabasen och Azure Database for MySQL-målet.

Om du vill exportera schemat med mysqldump kör du följande kommando:

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

Till exempel:

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

Kör följande kommando för att importera schemat för att rikta in sig på Azure Database for MySQL:

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

Till exempel:

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

Om du har sekundärnycklar i schemat hanteras den parallella databelastningen under migreringen av migreringsuppgiften. Du behöver inte släppa sekundärnycklar under schemamigreringen.

Om du har utlösare i databasen framtvingar den dataintegriteten i målet före fullständig datamigrering från källan. Rekommendationen är att inaktivera utlösare på alla tabeller i målet under migreringen och sedan aktivera utlösarna när migreringen är klar.

Kör följande skript i MySQL Workbench på måldatabasen för att extrahera släpputlösarskriptet och lägga till utlösarskript.

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;

Kör den genererade släpputlösarfrågan (dropQuery-kolumnen) i resultatet för att släppa utlösare i måldatabasen. Du kan spara frågan lägg till utlösare som ska användas efter att datamigreringen har slutförts.

Logga in på din Microsoft Azure-prenumeration

Använd Kommandot Connect-AzAccount PowerShell för att logga in på din Azure-prenumeration med hjälp av PowerShell, enligt anvisningarna i artikeln Logga in med Azure PowerShell.

Följande skript anger standardprenumerationen för PowerShell-sessionen efter inloggningen och skapar en hjälploggningsfunktion för formaterade konsolloggar.

[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
    }
}

Registrera resursprovidern Microsoft.DataMigration

Registrering av resursprovidern behöver endast göras för varje Azure-prenumeration en gång. Utan registreringen kan du inte skapa en instans av Azure Database Migration Service.

Registrera resursprovidern med hjälp av kommandot Register-AzResourceProvider . Följande skript registrerar resursprovidern som krävs för Azure Database Migration Service

Register-AzResourceProvider -ProviderNamespace Microsoft.DataMigration

Skapa en resursgrupp

En Azure-resursgrupp är en logisk container där Azure-resurser distribueras och hanteras. Skapa en resursgrupp innan du skapar dms-resurser.

Skapa en resursgrupp med kommandot New-AzResourceGroup .

I följande exempel skapas en resursgrupp med namnet myResourceGroup i regionen USA, västra 2 under standardprenumerationen 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." }

Skapa en instans av Azure Database Migration Service

Du kan skapa en ny instans av Azure Database Migration Service med hjälp av kommandot New-AzDataMigrationService . Det här kommandot förväntar sig följande obligatoriska parametrar:

  • Namn på Azure-resursgrupp. Du kan använda kommandot New-AzResourceGroup för att skapa En Azure-resursgrupp som tidigare visats och ange dess namn som en parameter.

  • Tjänstnamn. Sträng som motsvarar önskat unikt tjänstnamn för Azure Database Migration Service

  • Plats. Anger platsen för tjänsten. Ange en Azure-datacenterplats, till exempel USA, västra eller Asien, sydöstra

  • Sku. Den här parametern motsvarar DMS Sku-namnet. Det Sku-namn som stöds för närvarande är Standard_1vCore, Standard_2vCores, Standard_4vCores, Premium_4vCores.

  • Virtuell undernätsidentifierare. Du kan använda kommandot Get-AzVirtualNetworkSubnetConfig för att hämta information om ett undernät.

Följande skript förväntar sig att det virtuella nätverket myVirtualNetwork finns med ett undernät med namnet default och skapar sedan en databasmigreringstjänst med namnet myDmService under resursgruppen som skapades i steg 3 och i samma region.

# 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." }

Skapa ett migreringsprojekt

När du har skapat en Azure Database Migration Service-instans skapar du ett migreringsprojekt. Ett migreringsprojekt anger vilken typ av migrering som måste utföras.

Följande skript skapar ett migreringsprojekt med namnet myfirstmysqlofflineproject för offlinemigrering från MySQL till Azure Database for MySQL under Database Migration Service-instansen som skapades i steg 4 och i samma region.

# 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." }

Skapa ett databasanslutningsinformationsobjekt för käll- och målanslutningarna

När du har skapat migreringsprojektet skapar du information om databasanslutningen. Den här anslutningsinformationen används för att ansluta till käll- och målservrarna under migreringsprocessen.

Följande skript tar servernamnet, användarnamnet och lösenordet för mySQL-käll- och målinstanserna och skapar anslutningsinformationsobjekten. Skriptet uppmanar användaren att ange lösenordet för mySQL-käll- och målinstanserna. För tysta skript kan autentiseringsuppgifterna hämtas från 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."

Extrahera listan med tabellnamn från måldatabasen

Databastabelllistan kan extraheras med hjälp av en migreringsaktivitet och anslutningsinformation. Tabelllistan extraheras från både källdatabasen och måldatabasen så att rätt mappning och validering kan göras.

Följande skript tar namnen på käll- och måldatabaserna och extraherar sedan tabelllistan från databaserna med migreringsuppgiften 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."

Skapa tabellmappning baserat på användarkonfiguration

Som en del av konfigurationen av migreringsuppgiften skapar du en mappning mellan käll- och måltabellerna. Mappningen är på tabellnamnsnivå, men antagandet är att tabellstrukturen (kolumnantal, kolumnnamn, datatyper osv.) för de mappade tabellerna är exakt densamma.

Följande skript skapar en mappning baserat på mål- och källtabelllistan som extraherades i steg 7. För partiell datainläsning kan användaren ange en lista med tabeller för att filtrera bort tabellerna. Om inga användarindata anges mappas alla måltabeller. Skriptet kontrollerar också om det finns en tabell med samma namn i källan eller inte. Om tabellnamnet inte finns i källan ignoreras måltabellen för migrering.

# 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."

Skapa och konfigurera migreringsaktivitetsindata

När du har skapat tabellmappningen skapar du indata för migreringsuppgiften av typen Migrate.MySql.AzureDbForMySql och konfigurerar egenskaperna.

Följande skript skapar migreringsuppgiften och anger anslutningar, databasnamn och tabellmappning.

# 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");

Konfigurera prestandajusteringsparametrar

Som en del av PowerShell-modulen finns det få valfria parametrar som kan justeras baserat på miljön. Dessa parametrar kan användas för att förbättra migreringsaktivitetens prestanda. Alla dessa parametrar är valfria och deras standardvärde är NULL.

Följande prestandakonfigurationer har visat ökat dataflöde under migreringen på Premium SKU.

  • WriteDataRangeBatchTaskCount = 12

  • DelayProgressUpdatesInStorageInterval = 30 sekunder

  • ThrottleQueryTableDataRangeTaskAtBatchCount = 36

Följande skript tar användarvärdena för parametrarna och anger parametrarna i egenskaperna för migreringsaktiviteten.

# 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;

Skapa och köra migreringsuppgiften

När du har konfigurerat indata för aktiviteten skapas och körs aktiviteten på agenten. Skriptet utlöser uppgiftskörningen och väntar tills migreringen har slutförts.

Följande skript anropar den konfigurerade migreringsuppgiften och väntar tills den har slutförts.

# 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
}

Ta bort databasmigreringstjänsten

Samma databasmigreringstjänst kan användas för flera migreringar så att instansen när den har skapats kan återanvändas. Om du inte kommer att fortsätta att använda Database Migration Service kan du ta bort tjänsten med kommandot Remove-AzDataMigrationService .

Följande skript tar bort Azure Database Migration Service-instansen och dess associerade projekt.

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