Перенос MySQL в Базу данных Azure для MySQL в автономном режиме с помощью PowerShell и Azure Database Migration Service
В этой статье вы перенесете базу данных MySQL, восстановленную в локальном экземпляре, в Базу данных Azure для MySQL, используя возможность автономной миграции Azure Database Migration Service с помощью Microsoft Azure PowerShell. В этой статье описывается коллекция скриптов PowerShell, которые можно выполнять последовательно для автономной миграции базы данных MySQL в Azure. Полный скрипт PowerShell, описанный в этом руководстве, можно скачать из нашего репозитория GitHub.
Примечание.
В настоящее время невозможно выполнить полную миграцию базы данных с помощью модуля Az.DataMigration. В то же время пример скрипта PowerShell предоставляется как есть, который использует REST API DMS и позволяет автоматизировать миграцию. Этот скрипт будет изменен или переведен в категорию нерекомендуемых после добавления официальной поддержки в модуль Az.DataMigration и Azure CLI.
Служба реляционной базы данных Amazon (RDS) для MySQL и Amazon Aurora (на основе MySQL) также поддерживаются в качестве источников для миграции.
Внимание
Для интерактивной миграции также можно использовать средства с открытым кодом, например MyDumper/MyLoader с репликацией входных данных.
Эта статья поможет автоматизировать миграцию в сценариях, когда имена исходной и целевой баз данных могут быть одинаковыми или разными и в процессе миграции все или несколько таблиц в целевой базе данных должны быть перенесены с теми же именами и структурами таблиц. Хотя в статьях предполагается, что источником является экземпляр базы данных MySQL, а целевым объектом — База данных Azure для MySQL, эти инструкции можно использовать для миграции из одной Базы данных Azure для MySQL в другую, просто изменив имя исходного сервера и учетные данные. Кроме того, поддерживается миграция с серверов MySQL более ранних версий (версия 5.6 и выше) в более поздние.
Внимание
Предварительные версии функций DMS доступны на уровне самообслуживания. Предварительные версии предоставляются "как есть" и "при наличии". На них не распространяются соглашения об уровне обслуживания и ограниченная гарантия. Следовательно, эти функции не предназначены для использования в рабочей среде. Дополнительные сведения см. в статье Дополнительные условия использования Предварительных версий Microsoft Azure.
Вы узнаете, как выполнять следующие задачи:
- Миграция схемы базы данных.
- Создать группу ресурсов.
- создание экземпляра Azure Database Migration Service;
- создание проекта миграции в экземпляре Azure Database Migration Service;
- Настройка проекта миграции для использования возможности автономной миграции для MySQL.
- выполнение миграции.
Необходимые компоненты
Для выполнения этих действий вам потребуется следующее:
Подготовьте учетную запись Azure с активной подпиской. Создайте учетную запись бесплатно .
У вас должна быть локальная база данных MySQL с версией 5.6 или более поздней. Если ее нет, скачайте и установите MySQL Community Edition версии 5.6 или более поздней.
Создайте экземпляр в Базе данных Azure для MySQL. Ознакомьтесь со статьей Подключение и запрос данных с помощью MySQL Workbench, чтобы узнать, как подключить и создать базу данных с помощью приложения Workbench. Версия Базы данных Azure для MySQL должна быть не ниже, чем версия локальной базы данных MySQL. Например, MySQL версии 5.7 можно перенести в Базу данных Azure для MySQL версии 5.7 или 8.
Создайте виртуальную сеть Microsoft Azure для Azure Database Migration Service с помощью модели развертывания Azure Resource Manager, которая обеспечивает подключение "сеть — сеть" к локальным исходным серверам с помощью ExpressRoute или VPN. Дополнительные сведения см. в статье Документация по виртуальной сети, где особое внимание стоит уделить кратким руководствам с пошаговыми инструкциями.
Примечание.
Если вы используете ExpressRoute с пиринговым подключением к сети, управляемой Майкрософт, во время настройки виртуальной сети добавьте в подсеть, в которой будет подготовлена служба, конечную точку службы Microsoft.Sql. Такая конфигурация вызвана тем, что у Azure Database Migration Service нет подключения к Интернету.
Убедитесь, что правила группы безопасности сети для виртуальной сети не блокируют исходящий порт 443 ServiceTag для службы хранилища и Azure Monitor. См. дополнительные сведения о фильтрации трафика, предназначенного для виртуальной сети, с помощью групп безопасности сети.
Откройте брандмауэр Windows, чтобы разрешить подключения из виртуальной сети для Azure Database Migration Service для доступа к исходному серверу MySQL Server. По умолчанию это TCP-порт 3306.
При использовании устройства брандмауэра перед исходными базами данных может потребоваться добавить правила брандмауэра, чтобы разрешить подключения от виртуальная сеть для Azure Database Migration Service для доступа к исходным базам данных для миграции.
Создайте правило брандмауэра уровня сервера или настройте конечные точки службы виртуальной сети для целевой Базы данных Azure для MySQL, чтобы предоставить виртуальной сети службы Azure Database Migration Service доступ к целевым базам данных.
Исходный экземпляр MySQL должен находиться в поддерживаемой версии MySQL Community Edition. Чтобы определить версию экземпляра MySQL, в служебной программе MySQL или MySQL Workbench выполните следующую команду:
SELECT @@VERSION;
База данных Azure для MySQL поддерживает только таблицы InnoDB. Чтобы преобразовать таблицы MyISAM в InnoDB, ознакомьтесь со сведениями на странице о преобразовании таблиц.
Пользователь должен иметь права доступа для чтения данных в базе данных — источнике.
В руководстве используется PowerShell версии 7.2, которую можно установить в рамках руководства по установке.
Скачайте и установите следующие модули из коллекции PowerShell с помощью командлета установки модулей PowerShell. Откройте командное окно PowerShell от имени администратора:
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
Миграция схемы базы данных
Чтобы перенести все объекты базы данных, такие как схемы таблицы, индексы и хранимые процедуры, нам нужно извлечь схему из базы данных — источника и применить ее к целевой базе данных. Чтобы извлечь схему, можно использовать mysqldump с параметром --no-data
. Для этого вам потребуется компьютер, который может подключаться как к исходной базе данных MySQL, так и к целевой Базе данных Azure для MySQL.
Чтобы экспортировать схему с помощью mysqldump, выполните следующую команду:
mysqldump -h [servername] -u [username] -p[password] --databases [db name] --no-data > [schema file path]
Например:
mysqldump -h 10.10.123.123 -u root -p --databases migtestdb --no-data > d:\migtestdb.sql
Чтобы импортировать схему в целевую Базу данных Azure для MySQL, выполните следующую команду:
mysql.exe -h [servername] -u [username] -p[password] [database]< [schema file path]
Например:
mysql.exe -h mysqlsstrgt.mysql.database.azure.com -u docadmin@mysqlsstrgt -p migtestdb < d:\migtestdb.sql
При наличии внешних ключей в схеме загрузка параллельных данных во время миграции будет обрабатываться задачей миграции. Во время миграции схемы не нужно удалять внешние ключи.
Если у вас есть триггеры в базе данных, они будут обеспечивать целостность данных в целевом объекте до полного переноса данных из источника. Рекомендуется отключить триггеры во всех таблицах целевого объекта во время миграции, а затем включить их после завершения миграции.
Выполните следующий скрипт в MySQL Workbench в целевой базе данных, чтобы извлечь скрипт удаления триггера и скрипт добавления триггера.
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;
Выполните созданный запрос на удаление триггера (столбец DropQuery) в результатах, чтобы удалить триггеры в целевой базе данных. Запрос на добавление триггера можно сохранить, чтобы использовать после завершения переноса данных.
Вход в подписку Microsoft Azure
Используйте команду PowerShell Connect-AzAccount, чтобы войти в подписку Azure с помощью PowerShell, согласно инструкциям в статье Вход в систему с помощью Azure PowerShell.
Следующий скрипт задает подписку по умолчанию для сеанса PowerShell после входа и создает вспомогательную функцию ведения журнала для форматированных журналов консоли.
[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
}
}
Зарегистрируйте поставщик ресурсов Microsoft.DataMigration.
Регистрация поставщика ресурсов должна выполняться в каждой подписке Azure только один раз. Без регистрации вы не сможете создать экземпляр Azure Database Migration Service.
Зарегистрируйте поставщик ресурсов с помощью команды Register-AzResourceProvider. Следующий скрипт регистрирует поставщик ресурсов, необходимый для Azure Database Migration Service
Register-AzResourceProvider -ProviderNamespace Microsoft.DataMigration
Создание или изменение группы ресурсов
Группа ресурсов Azure является логическим контейнером, в котором происходит развертывание ресурсов Azure и управление ими. Перед созданием ресурсов DMS создайте группу ресурсов.
Создайте группу ресурсов с помощью команды New-AzResourceGroup.
В следующем примере создается группа ресурсов с именем myResourceGroup в регионе Западная часть США 2 в подписке по умолчанию 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." }
Создание экземпляра Azure Database Migration Service
Вы можете создать экземпляр Azure Database Migration Service, выполнив команду New-AzDataMigrationService. Для этой команды нужно передать следующие обязательные параметры:
ResourceGroupName. Вы можете выполнить команду New-AzResourceGroup, чтобы создать группу ресурсов Azure, как описано выше, и указать ее имя в качестве параметра.
ServiceName. Строка, соответствующая требуемому уникальному имени службы для Azure Database Migration Service.
Location. Указывает расположение службы. Укажите расположение центра обработки данных Azure, например западная часть США или Юго-Восточная Азия.
Sku. Этот параметр соответствует имени SKU DMS. В настоящее время поддерживаются следующие имена SKU: Standard_1vCore, Standard_2vCores, Standard_4vCores, Premium_4vCores.
VirtualSubnetId. Для получения сведений о подсети можно использовать команду Get-AzVirtualNetworkSubnetConfig.
Следующий скрипт ожидает, что виртуальная сеть myVirtualNetwork существует в подсети с именем по умолчанию, а затем создает Database Migration Service с именем myDmService в группе ресурсов, созданной на шаге 3, в том же регионе.
# 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." }
Создание проекта миграции
После создания экземпляра Azure Database Migration Service вы создадите проект миграции. Проект миграции определяет тип миграции, который необходимо выполнить.
Следующий скрипт создает проект миграции с именем myfirstmysqlofflineproject для автономной миграции из MySQL в Базу данных Azure для MySQL в экземпляре Database Migration Service, созданном на шаге 4, в том же регионе.
# 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." }
Создание объекта сведений о подключении к базе данных для исходных и целевых подключений
После создания проекта миграции вы создадите сведения о подключении к базе данных. Эти сведения о подключении будут использоваться для подключения к исходным и целевым серверам в процессе миграции.
Следующий скрипт принимает имя сервера, имя пользователя и пароль для исходного и целевого экземпляров MySQL и создает объекты сведений о подключении. Скрипт предлагает пользователю ввести пароль для исходного и целевого экземпляров MySQL. Для автоматических скриптов учетные данные можно получить из 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."
Извлечение списка имен таблиц из целевой базы данных
Список таблиц базы данных можно извлечь с помощью задачи миграции и сведений о подключении. Список таблиц будет извлечен из исходной и целевой баз данных, чтобы можно было выполнить правильное сопоставление и проверку.
Следующий скрипт принимает имена исходной и целевой баз данных, а затем извлекает список таблиц из баз данных с помощью задачи миграции 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."
Создание сопоставления таблиц на основе пользовательской конфигурации
В рамках настройки задачи миграции вы создадите сопоставление между исходными и целевыми таблицами. Сопоставление выполняется на уровне имени таблицы, но предполагается, что структура таблицы (количество столбцов, имена столбцов, типы данных и т. д.) для сопоставленных таблиц совпадают.
Следующий скрипт создает сопоставление на основе списка целевых и исходных таблиц, извлеченных на шаге 7. Для частичной загрузки данных пользователь может предоставить список таблиц для фильтрации. Если пользователь не указывает никакие данные, сопоставляются все целевые таблицы. Скрипт также проверяет, существует ли в источнике таблица с тем же именем. Если имя таблицы не существует в источнике, целевая таблица игнорируется для миграции.
# 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."
Создание и настройка входных данных задачи миграции
После создания сопоставления таблиц вы создадите входные данные для задачи миграции типа Migration.MySql.AzureDbForMySql и настройте свойства.
Следующий скрипт создает задачу миграции и задает подключения, имена баз данных и сопоставление таблиц.
# 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");
Конфигурация параметров настройки производительности
Для модуля PowerShell доступно несколько необязательных параметров, которые можно настроить в зависимости от среды. Эти параметры можно использовать для повышения производительности задачи миграции. Все эти параметры являются необязательными и их значение NULL
по умолчанию.
В следующих конфигурациях производительности показана увеличенная пропускная способность во время миграции в номере SKU "Премиум".
WriteDataRangeBatchTaskCount = 12
DelayProgressUpdatesInStorageInterval = 30 с
ThrottleQueryTableDataRangeTaskAtBatchCount = 36
Следующий скрипт принимает значения параметров пользователя и задает параметры в свойствах задачи миграции.
# 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;
Создание и выполнение задачи миграции
После настройки входных данных для задачи она будет создана и выполнена на агенте. Скрипт запускает выполнение задачи и ожидает завершения миграции.
Следующий скрипт вызывает настроенную задачу миграции и ожидает ее завершения.
# 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
}
Удаление Службы миграции базы данных
Один и тот же созданный экземпляр Database Migration Service можно использовать для нескольких операций миграции. Если вы не собираетесь дальше использовать Database Migration Service, можно удалить службу с помощью команды Remove-AzDataMigrationService.
Следующий скрипт удаляет экземпляр Azure Database Migration Service и связанные с ним проекты.
Remove-AzDataMigrationService -ResourceId $($dmsService.ResourceId)
Связанный контент
- Устранение распространенных проблем и ошибок Azure Database Migration Service (классическая версия)
- Troubleshoot DMS errors when connecting to source databases (Устранение ошибок DMS при подключении к базам данных-источникам)
- Что такое служба Azure Database Migration Service?
- Что такое База данных Azure для MySQL?
- Руководство. Перенос MySQL в автономный База данных Azure для MySQL режим с помощью DMS