Melakukan migrasi MySQL ke Azure Database for MySQL offline dengan PowerShell & Azure Database Migration Service

Dalam artikel ini, Anda memigrasikan database MySQL yang dipulihkan pada instans lokal ke Azure Database for MySQL menggunakan kemampuan migrasi offline Azure Database Migration Service melalui Microsoft Azure PowerShell. Artikel ini mendokumentasikan kumpulan skrip PowerShell yang dapat dijalankan secara berurutan untuk melakukan migrasi offline database MySQL ke Azure. Anda dapat mengunduh skrip PowerShell lengkap yang dijelaskan dalam tutorial ini dari repositori GitHub kami.

Catatan

Saat ini tidak dimungkinkan untuk menjalankan migrasi database lengkap menggunakan modul Az.DataMigration. Sementara itu, sampel skrip PowerShell disediakan "apa adanya" yang menggunakan DMS REST API dan memungkinkan Anda mengotomatiskan migrasi. Skrip ini akan dimodifikasi atau tidak digunakan lagi, setelah dukungan resmi ditambahkan dalam modul Az.DataMigration dan Azure CLI.

Catatan

Amazon Relational Database Service (RDS) untuk MySQL dan Amazon Aurora (berbasis MySQL) juga didukung sebagai sumber migrasi.

Penting

Untuk migrasi online, Anda dapat menggunakan alat sumber terbuka seperti MyDumper/MyLoader dengan replikasi data masuk.

Artikel ini membantu mengotomatisasi skenario di mana nama database sumber dan target bisa sama atau berbeda dan sebagai bagian dari migrasi baik semua atau beberapa tabel dalam database target perlu dimigrasikan, yang memiliki nama dan struktur tabel yang sama. Meskipun artikel menganggap sumbernya sebagai instans database MySQL dan target sebagai Azure Database for MySQL, artikel ini dapat digunakan untuk bermigrasi dari satu Azure Database for MySQL ke yang lain hanya dengan mengubah nama server sumber dan kredensial. Selain itu, migrasi dari server MySQL versi lebih lama (v5.6 dan yang lebih lama) ke versi yang lebih baru juga didukung.

Penting

Fitur pratinjau DMS tersedia berdasarkan layanan mandiri, berdasarkan pilih ikut. Pratinjau disediakan "apa adanya" dan "sebagaimana tersedia," dan mereka dikecualikan dari perjanjian tingkat layanan dan garansi terbatas. Dengan demikian, fitur-fitur ini tidak dimaksudkan untuk penggunaan produksi. Untuk mengetahui informasi selengkapnya, lihat Ketentuan penggunaan tambahan untuk pratinjau Microsoft Azure.

Dalam artikel ini, Anda akan mempelajari cara:

  • Memigrasikan skema database.
  • Membuat grup sumber daya.
  • Membuat instans Azure Database Migration Service.
  • Membuat proyek migrasi dalam instans Azure Database Migration Service.
  • Mengonfigurasi proyek migrasi untuk menggunakan kemampuan migrasi offline untuk MySQL.
  • Menjalankan migrasi.

Prasyarat

Untuk menyelesaikan langkah-langkah ini, Anda perlu:

  • Memiliki akun Azure dengan langganan aktif. Membuat akun secara gratis.

  • Memiliki database MySQL lokal dengan versi 5.6 atau lebih baru. Jika tidak, maka unduh dan instal edisi komunitas MySQL 5.6 atau lebih baru.

  • Membuat instans Azure Database for MySQL. Lihat artikel Menggunakan MySQL Workbench untuk menyambungkan dan mengkueri data untuk detail tentang cara menyambungkan dan membuat database menggunakan aplikasi Workbench. Versi Azure Database for MySQL harus sama dengan atau lebih baru dari versi MySQL lokal . Misalnya, MySQL 5.7 dapat bermigrasi ke Azure Database for MySQL 5.7 atau ditingkatkan menjadi 8.

  • Buat Microsoft Azure Virtual Network for Azure Database Migration Service dengan menggunakan model penyebaran Azure Resource Manager, yang menyediakan konektivitas antar-situs ke server sumber lokal Anda dengan menggunakan ExpressRoute atau VPN. Untuk informasi selengkapnya tentang membuat jaringan virtual, lihat Dokumentasi Jaringan Virtual, dan terutama artikel mulai cepat yang disertai detail langkah demi langkah.

    Catatan

    Selama penyiapan jaringanNet virtual, jika Anda menggunakan ExpressRoute dengan peering jaringan ke Microsoft, tambahkan titik akhir layanan Microsoft.Sql ke subnet tempat layanan akan diprovisikan. Konfigurasi ini diperlukan karena Azure Database Migration Service tidak memiliki konektivitas internet.

  • Pastikan aturan Kelompok Keamanan Jaringan pada jaringan virtual tidak memblokir port keluar 443 ServiceTag untuk Storage dan AzureMonitor. Untuk mengetahui detail selengkapnya tentang pemfilteran lalu lintas NSG jaringan virtual, lihat artikel Memfilter lalu lintas dengan kelompok keamanan jaringan.

  • Buka firewall Windows Anda untuk mengizinkan koneksi dari Virtual Network for Azure Database Migration Service agar dapat mengakses MySQL Server sumber, yang secara default adalah port TCP 3306.

  • Saat menggunakan perangkat firewall di depan database sumber, Anda mungkin perlu menambahkan aturan firewall untuk mengizinkan koneksi dari Virtual Network for Azure Database Migration Service guna mengakses database sumber untuk migrasi.

  • Buat aturan firewall tingkat server atau konfigurasi titik akhir layanan VNET untuk Azure Database for MySQL target untuk memungkinkan akses Virtual Network for Azure Database Migration Service ke database target.

  • MySQL sumber harus menggunakan edisi komunitas MySQL yang didukung. Untuk menentukan versi instans MySQL, dalam utilitas MySQL atau MySQL Workbench, jalankan perintah berikut:

    SELECT @@version;
    
  • Azure Database for MySQL hanya mendukung tabel InnoDB. Untuk mengonversi tabel MyISAM ke InnoDB, lihat artikel Mengonversi Tabel dari MyISAM ke InnoDB

  • Pengguna harus memiliki hak istimewa untuk membaca data pada database sumber.

  • Panduan ini menggunakan PowerShell v7.2, yang dapat diinstal sesuai panduan penginstalan

  • Unduh dan instal modul berikut dari Galeri PowerShell menggunakan cmdlet Install-Module PowerShell; pastikan untuk membuka jendela perintah PowerShell menggunakan jalankan sebagai Administrator:

    • 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

Memigrasikan skema database

Untuk mentransfer semua objek database seperti skema tabel, indeks, dan prosedur tersimpan, kita perlu mengekstrak skema dari database sumber dan menerapkannya ke database target. Untuk mengekstrak skema, Anda dapat menggunakan mysqldump dengan parameter --no-data. Untuk ini, Anda memerlukan komputer yang dapat tersambung ke database MySQL sumber dan Azure Database for MySQL target.

Untuk mengekspor skema menggunakan mysqldump, jalankan perintah berikut:

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

Contohnya:

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

Untuk mengimpor skema ke Azure Database for MySQL target, jalankan perintah berikut:

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

Contohnya:

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

Jika Anda memiliki kunci asing dalam skema Anda, pemuatan data paralel selama migrasi akan ditangani oleh tugas migrasi. Tidak perlu menghilangkan kunci asing selama migrasi skema.

Jika Anda memiliki pemicu dalam database, ini akan memberlakukan integritas data dalam target menjelang migrasi data penuh dari sumber. Direkomendasikan agar Anda menonaktifkan pemicu di semua tabel pada target selama migrasi, lalu mengaktifkan pemicu setelah migrasi selesai.

Jalankan skrip berikut di MySQL Workbench pada database target untuk mengekstrak skrip hapus pemicu dan skrip tambahkan pemicu.

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

Jalankan kueri hapus pemicu yang dibuat (kolom DropQuery) dalam hasil untuk menghapus pemicu dalam database target. Kueri tambahkan pemicu dapat disimpan, untuk digunakan setelah penyelesaian migrasi data.

Masuk ke langganan Microsoft Azure Anda

Gunakan perintah Connect-AzAccount PowerShell untuk masuk ke langganan Azure Anda menggunakan PowerShell, sesuai petunjuk dalam artikel Masuk dengan Azure PowerShell.

Skrip berikut ini menetapkan langganan default untuk login posting sesi PowerShell dan membuat fungsi pengelogan pembantu untuk log konsol yang diformat.

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

Mendaftarkan penyedia sumber daya Microsoft.DataMigration

Pendaftaran penyedia sumber daya perlu dilakukan hanya sekali pada setiap langganan Azure. Tanpa pendaftaran, Anda tidak akan dapat membuat instans Azure Database Migration Service.

Daftarkan penyedia sumber daya menggunakan perintah Register-AzResourceProvider. Skrip berikut mendaftarkan penyedia sumber daya yang diperlukan untuk Azure Database Migration Service

Register-AzResourceProvider -ProviderNamespace Microsoft.DataMigration

Membuat grup sumber daya

Grup sumber daya Azure adalah kontainer logis yang disebarkan dan dikelola sumber daya Azure. Buat grup sumber daya sebelum Anda membuat sumber daya DMS apa pun.

Buat grup sumber daya menggunakan perintah New-AzResourceGroup.

Contoh berikut membuat grup sumber daya bernama myResourceGroup di wilayah US Barat 2 pada langganan default 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." }

Membuat instans Azure Database Migration Service

Anda dapat membuat instans baru Azure Database Migration Service menggunakan perintah New-AzDataMigrationService. Perintah ini mengharapkan parameter yang diperlukan berikut:

  • Nama grup sumber daya Azure. Anda dapat menggunakan perintah New-AzResourceGroup untuk membuat grup Sumber Daya Azure seperti yang ditunjukkan sebelumnya dan memberi nama sebagai parameter.
  • Nama layanan. Untai (karakter) yang sesuai dengan nama layanan unik yang diinginkan untuk Azure Database Migration Service
  • Lokasi. Menentukan lokasi layanan. Menentukan lokasi pusat data Azure, seperti US Barat atau Asia Tenggara
  • Sku. Parameter ini sesuai dengan nama Sku DMS. Nama Sku yang saat ini didukung adalah Standard_1vCore, Standard_2vCores, Standard_4vCores, Premium_4vCores.
  • Pengidentifikasi Subnet Virtual. Anda dapat menggunakan perintah Get-AzVirtualNetworkSubnetConfig untuk mendapatkan informasi subnet.

Skrip berikut mengharapkan agar jaringan virtual myVirtualNetwork ada dengan subnet bernama default kemudian membuat Database Migration Service dengan nama myDmService pada grup sumber daya yang dibuat di Langkah 3 dan di wilayah yang sama.

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

Membuat proyek migrasi

Setelah membuat instans Azure Database Migration Service, Anda akan membuat proyek migrasi. Proyek migrasi menentukan jenis migrasi yang perlu dilakukan.

Skrip berikut membuat proyek migrasi bernama myfirstmysqlofflineproject untuk migrasi offline dari MySQL ke Azure Database for MySQL pada instans Database Migration Service yang dibuat di Langkah 4 dan di wilayah yang sama.

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

Membuat objek Info Koneksi Database untuk koneksi sumber dan target

Setelah membuat proyek migrasi, Anda akan membuat informasi koneksi database. Informasi koneksi ini akan digunakan untuk menyambungkan ke server sumber dan target selama proses migrasi.

Skrip berikut mengambil nama server, nama pengguna, dan kata sandi untuk instans MySQL sumber dan target serta membuat objek informasi koneksi. Skrip meminta pengguna untuk memasukkan kata sandi untuk instans MySQL sumber dan target. Untuk skrip diam, kredensial dapat diambil dari 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."

Mengekstrak daftar nama tabel dari database target

Daftar tabel database dapat diekstrak menggunakan tugas migrasi dan informasi koneksi. Daftar tabel akan diekstrak dari database sumber dan database target sehingga pemetaan dan validasi yang tepat dapat dilakukan.

Skrip berikut ini mengambil nama database sumber dan target lalu mengekstrak daftar tabel dari database menggunakan tugas migrasi 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."

Menyusun pemetaan tabel berdasarkan konfigurasi pengguna

Sebagai bagian dari konfigurasi tugas migrasi, Anda akan membuat pemetaan antara tabel sumber dan target. Pemetaan berada pada tingkat nama tabel namun asumsinya adalah bahwa struktur tabel (jumlah kolom, nama kolom, jenis data, dll.) dari tabel yang dipetakan persis sama.

Skrip berikut membuat pemetaan berdasarkan daftar tabel target dan sumber yang diekstrak di Langkah 7. Untuk pemuatan data parsial, pengguna dapat menyediakan daftar tabel untuk memfilter tabel. Jika input pengguna tidak tersedia, maka semua tabel target dipetakan. Skrip juga memeriksa apakah tabel dengan nama yang sama ada di sumber atau tidak. Jika nama tabel tidak ada di sumber, maka tabel target diabaikan untuk migrasi.

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

Membuat dan mengonfigurasi input tugas migrasi

Setelah menyusun pemetaan tabel, Anda akan membuat input untuk tugas migrasi jenis Migrate.MySql.AzureDbForMySql dan mengonfigurasi properti.

Skrip berikut ini membuat tugas migrasi dan mengatur koneksi, nama database, dan pemetaan tabel.

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

Mengonfigurasi parameter penyetelan performa

Sesuai modul PowerShell, ada beberapa parameter opsional yang tersedia, yang dapat disetel berdasarkan lingkungan. Parameter ini dapat digunakan untuk meningkatkan performa tugas migrasi. Semua parameter ini bersifat opsional dan nilai defaultnya adalah NULL.

Catatan

Konfigurasi performa berikut telah menunjukkan peningkatan throughput selama migrasi pada SKU Premium.

  • WriteDataRangeBatchTaskCount = 12
  • DelayProgressUpdatesInStorageInterval = 30 detik
  • ThrottleQueryTableDataRangeTaskAtBatchCount = 36

Skrip berikut ini mengambil nilai pengguna parameter dan mengatur parameter dalam properti tugas migrasi.

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

Membuat dan menjalankan tugas migrasi

Setelah mengonfigurasi input untuk tugas, sekarang tugas akan dibuat dan dijalankan pada agen. Skrip memicu eksekusi tugas dan menunggu migrasi selesai.

Skrip berikut ini memanggil tugas migrasi yang dikonfigurasi dan menunggunya selesai.

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

Menghapus Database Migration Service

Database Migration Service yang sama dapat digunakan untuk beberapa migrasi agar instans dapat digunakan kembali setelah dibuat. Jika Anda tidak akan terus menggunakan Database Migration Service, maka Anda bisa menghapus layanan menggunakan perintah Remove-AzDataMigrationService.

Skrip berikut ini menghapus instans Azure Database Migration Service dan proyek terkaitnya.

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

Langkah berikutnya