共用方式為


將 MySQL 內部部署移轉至適用於 MySQL 的 Azure 資料庫:資料移轉

適用於:適用於 MySQL 的 Azure 資料庫 - 單一伺服器適用於 MySQL 的 Azure 資料庫 - 彈性伺服器

必要條件

效能基準

備份資料庫

為求謹慎,在升級或移轉資料之前,請先匯出資料庫,然後再使用 MySQL Workbench 或透過 mysqldump 命令手動進行升級。

離線與線上的比較

選取移轉工具之前,應該先判斷移轉應於線上或離線進行。

  • 離線移轉會導致系統在進行移轉時關閉。 此選項可確保不會發生任何交易,且資料的狀態正是在 Azure 中還原時所預期的狀態。

  • 線上移轉會近乎即時地移轉資料。 當使用者或應用程式耗用資料工作負載時,便適合此選項。 此程序涉及使用如 binlog 或類似的複寫方法來複寫資料。

針對 WWI,其環境具有一些複雜的網路和安全性需求,不允許在目標移轉時間範圍內針對輸入和輸出連線套用適當的變更。 這些複雜度和需求基本上不需要考慮線上方法。

注意

如需離線與線上移轉的更多詳細資料,請檢閱規劃與評量一節。

資料漂移

離線移轉策略可能會造成資料漂移。 當新修改的來源資料與已移轉的資料不同步時,就會發生資料漂移。 發生這種情況時,需要完整匯出或差異匯出。 您可以停止資料庫的所有流量,然後執行匯出,藉以減輕此問題。 如果無法停止所有資料修改流量,則必須考慮漂移。

如果資料庫數據表沒有數值主鍵之類的數據行,或某些類型的修改,並在需要移轉的每個數據表中建立日期,則判斷變更可能會變得複雜。

例如,如果存在以數值為基礎的主索引鍵,且移轉是以排序次序匯入,則判斷匯入停止的位置,並從該位置重新開始則相對簡單。 如果沒有以數值為基礎的索引鍵,則可以利用修改和建立日期,然後再次以排序的方式匯入,以便您可以從目標中看到的最後一個日期重新開始移轉。

效能建議

Export

  • 使用可在多執行緒模式中執行的匯出工具,例如 mydumper

  • 使用 MySQL 8.0 時,請適當地使用資料分割資料表來提升匯出速度。

Import

  • 載入資料之後先建立叢集索引和主索引鍵。 以主索引鍵順序載入資料,或者,針對主索引鍵某些日期資料行 (例如修改日期或建立日期) 以排序次序載入資料。

  • 延遲建立次要索引,直到載入資料。 載入之後建立所有次要索引。

  • 載入之前停用外部索引鍵限制式。 停用外部索引鍵檢查會提供顯著的效能提升。 啟用限制式並且確認載入之後的資料,以確保參考完整性。

  • 平行載入資料。 避免會導致資源爭用的太多平行處理原則,以及使用 Azure 入口網站中可用的計量監視資源。

執行移轉。

  • 備份資料庫

  • 建立並驗證 Azure 登陸區域

  • 設定來源伺服器參數

  • 設定目標伺服器參數

  • 匯出資料庫物件 (結構描述、使用者等)

  • 匯出資料

  • 匯入資料庫物件

  • 匯入資料

  • 驗證

  • 重設目標伺服器參數

  • 移轉應用程式

通用步驟

無論使用何種路徑,仍必須執行通用步驟:

  • 升級至支援的 Azure MySQL 版本

  • 清查資料庫物件

  • 匯出使用者和權限

移轉至最新的 MySQL 版本

由於 WWI Conference 資料庫執行的是 5.5,因此必須執行升級。 CIO 要求他們升級至最新版的 MySQL (目前為 8.0)。

升級至 8.0 的方式有兩種:

  • 就地

  • 匯出/匯入

決定進行升級時,請務必執行升級檢查工具,以判斷是否有任何衝突。 例如,升級至 MySQL Server 8.0 時,此工具會檢查下列衝突:

  • 與 MySQL 8.0 中保留字衝突的資料庫物件名稱

  • 使用 utf8mb3 字元集

  • 使用 ZEROFILL/ 顯示長度類型屬性

  • 與 8.0 中資料表衝突的資料表名稱

  • 時態性類型使用方式

  • 外部索引鍵條件約束名稱長度超過 64 個字元

如果升級檢查程式回報沒有問題,您可以藉由取代 MySQL 二進位檔,安全地進行就地升級。 需要匯出具有問題的資料庫,並解決問題。

WWI 案例

成功將 MySQL 執行個體移轉至 8.0 之後,WWI 移轉小組發現原始資料移轉服務 (DMS) 移轉路徑無法再用作 DMS 工具,目前僅支援 5.6 和 5.7。 DMS 需要網路存取。 WWI 移轉小組尚未準備好處理其複雜的網路問題。 這些環境變數已將其移轉工具的選擇限縮為 MySQL Workbench。

資料庫物件

如「測試計畫」一節所述,移轉前後應該完成資料庫物件的清查,以確保您已移轉所有項目。

如果您想要執行預存程序來產生這項資訊,則可以使用類似下列的內容:

DELIMITER //
CREATE PROCEDURE `Migration_PerformInventory`(IN schemaName CHAR(64))
BEGIN

        DECLARE finished INTEGER DEFAULT 0;
          DECLARE tableName varchar(100) DEFAULT "";

        #get all tables
            DECLARE curTableNames
                CURSOR FOR
                    SELECT TABLE_NAME FROM information_schema.tables where TABL
E_SCHEMA = schemaName;

            -- declare NOT FOUND handler
            DECLARE CONTINUE HANDLER
                FOR NOT FOUND SET finished = 1;

            DROP TABLE IF EXISTS MIG_INVENTORY;

                CREATE TABLE MIG_INVENTORY
                (
                      REPORT_TYPE VARCHAR(1000),
                      OBJECT_NAME VARCHAR(1000),
                  PARENT_OBJECT_NAME VARCHAR (1000),
                      OBJECT_TYPE VARCHAR(1000),
                      COUNT INT
                )
                ROW_FORMAT=DYNAMIC,
                ENGINE='InnoDB';
              INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                     'OBJECTCOUNT', 'TABLES', 'TABLES', COUNT(*)
              FROM
                     information_schema.tables
                where
                     TABLE_SCHEMA = schemaName;
                #### Constraints
              INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                      'OBJECTCOUNT', 'STATISTICS', 'STATISTICS', COUNT(*)
                FROM
                      information_schema.STATISTICS
                WHERE
                      TABLE_SCHEMA = schemaName;
                INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                      'OBJECTCOUNT', 'VIEWS', 'VIEWS', COUNT(*)
                FROM
                      information_schema.VIEWS
                WHERE
                      ROUTINE_TYPE = 'FUNCTION' and
                      ROUTINE_SCHEMA = schemaName;

                INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                      'OBJECTCOUNT', 'PROCEDURES', 'PROCEDURES', COUNT(*)
                FROM
                      information_schema.ROUTINES
                WHERE
                      ROUTINE_TYPE = 'PROCEDURE' and
                      ROUTINE_SCHEMA = schemaName;

                INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                       'OBJECTCOUNT', 'EVENTS', 'EVENTS', COUNT(*)
                FROM
                       information_schema.EVENTS
                WHERE
                       EVENT_SCHEMA = schemaName;

                INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                       'OBJECTCOUNT', 'USER DEFINED FUNCTIONS', 'USER DEFINED FUNCTIONS'
        , COUNT(*)
                FROM
                        mysql.func;

                INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)
                SELECT
                        'OBJECTCOUNT', 'USERS', 'USERS', COUNT(*)
                FROM
                        mysql.user
                WHERE
                        user <> '' order by user;

                OPEN curTableNames;

                getTableName: LOOP
                        FETCH curTableNames INTO tableName;
                        IF finished = 1 THEN
                              LEAVE getTableName;
                        END IF;

                   SET @s = CONCAT('SELECT COUNT(*) into @TableCount FROM ', schemaName,
'.', tableName);
        #SELECT @s;
            PREPARE stmt FROM @s;
        EXECUTE stmt;
        INSERT INTO MIG_INVENTORY (REPORT_TYPE,OBJECT_NAME, OBJECT_TYPE, COUNT)

                SELECT
                    'TABLECOUNT', tableName, 'TABLECOUNT', @TableCount;
        DEALLOCATE PREPARE stmt;

     END LOOP getTableName;
     CLOSE curTableNames;

   SELECT * FROM MIG_INVENTORY;
END //

DELIMITER ;

CALL Migration_PerformInventory('reg_app');
  • 在來源資料庫上呼叫此程序會顯示下列內容 (截斷輸出):

截斷輸出的螢幕快照。

  • 完成移轉之後,目標資料庫程序結果應該類似於下圖。 請注意,資料庫中沒有函式。在移轉之前已排除函式。

DB 函式的螢幕快照。

使用者和權限

成功的移轉需要將相關聯的使用者和權限移轉至目標環境。

使用下列 PowerShell 指令碼來匯出所有使用者及其授與:

$username = "yourusername";
$password = "yourpassword";
mysql -u$username -p$password --skip-column-names -A -e"SELECT CONCAT('SHOW G
RANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" > Show
Grants.sql;

$lines = get-content "ShowGrants.sql"

foreach ($line in $lines)
{
mysql -u$username -p$password --skip-column-names -A -e"$line" >> AllGrants.sql
}
  • 使用 PowerShell ISE 建立新的 PowerShell 指令碼 (請參閱安裝文件)

  • 將使用者名稱設定為 root,並將密碼設定為根用戶的密碼

然後,您可以執行以新適用於 MySQL 的 Azure 資料庫為目標的 AllGrants.sql 指令碼:

$username = "yourusername";
$password = "yourpassword";
$server = "serverDNSname";
$lines = get-content "AllGrants.sql"

foreach ($line in $lines)
{
mysql -u$username -p$password -h$server --ssl-ca=c:\temp\BaltimoreCyberTrus
tRoot.crt.cer --skip-column-names -A -e"$line"
}

您也可以使用 PowerShell 在適用於 MySQL 的 Azure 資料庫中建立使用者:/en-us/azure/mysql/howto-create-users

執行移轉

有了基本移轉元件,現在可以繼續進行資料移轉。 先前導入了數個工具和方法。 針對 WWI,這些方法將會利用 MySQL Workbench 路徑來匯出資料,然後將其匯入適用於 MySQL 的 Azure 資料庫。

資料移轉檢查清單

  • 瞭解環境的複雜度,以及線上方法是否可行。

  • 考慮資料漂移。 停止資料庫服務可能會消除潛在的資料漂移。

  • 設定快速匯出的來源參數。

  • 設定快速匯入的目標參數。

  • 測試與目標具有不同來源版本的任何移轉。

  • 移轉任何非資料型物件,例如使用者名稱和權限。

  • 請確定在執行移轉時記錄並完成所有工作。

後續步驟