共用方式為


教學課程:透過 Azure CLI 使用 DMS (傳統版) 線上將 PostgreSQL 移轉至適用於 PostgreSQL 的 Azure 資料庫

重要

建議您在適用於 PostgreSQL 的 Azure 資料庫中使用新的移轉服務,以取得更簡化、更有效率的移轉體驗。 此服務可藉由支援各種來源環境來簡化流程,確保輕鬆轉換至適用於 PostgreSQL 的 Azure 資料庫。

您可以使用 Azure 資料庫移轉服務 (DMS),在最短的停機時間內將資料庫從內部部署 PostgreSQL 執行個體移轉至適用於 PostgreSQL 的 Azure 資料庫。 換句話說,可在最短的應用程式停機時間內完成移轉。 在此教學課程中,您會在 Azure 資料庫移轉服務中使用線上移轉活動,將 DVD Rental 範例資料庫從內部部署的 PostgreSQL 9.6 執行個體移轉至適用於 PostgreSQL 的 Azure 資料庫。

在本教學課程中,您會了解如何:

  • 使用 pg_dump 公用程式移轉範例結構描述。
  • 建立 Azure 資料庫移轉服務的執行個體。
  • 使用 Azure 資料庫移轉服務來建立移轉專案。
  • 執行移轉。
  • 監視移轉。

若要使用「Azure 資料庫移轉服務」來執行線上移轉,必須根據「進階」定價層建立執行個體。 我們會將磁碟加密,以防止在移轉期間使得資料遭竊。

重要

為了獲得最佳的移轉體驗,Microsoft 建議在目標資料庫所在的同一個 Azure 區域中,建立 Azure 資料庫移轉服務的執行個體。 跨區域或地理位置移動資料可能使移轉程序變慢,並產生錯誤。

必要條件

若要完成本教學課程,您需要:

  • 下載並安裝 PostgreSQL 社群版 9.4、9.5、9.6 或 10。 來源 PostgreSQL 伺服器版本必須是 9.4、9.5、9.6、10、11、12 或 13。 如需詳細資訊,請參閱支援的 PostgreSQL 資料庫版本。

    目標「適用於 PostgreSQL 的 Azure 資料庫」版本必須等於或晚於內部部署 PostgreSQL 版本。 例如,PostgreSQL 9.6 僅能遷移至適用於 PostgreSQL 的 Azure 資料庫 9.6、10 或 11,但無法遷移至適用於 PostgreSQL 的 Azure 資料庫 9.5。

  • 在適用於 PostgreSQL 的 Azure 資料庫建立執行個體 - 彈性伺服器。

  • 使用 Azure Resource Manager 部署模型建立適用於 Azure 資料庫移轉服務的 Microsoft Azure 虛擬網路,此模型會使用 ExpressRouteVPN 提供內部部署來源伺服器的站對站連線。 如需建立虛擬網路的詳細資訊,請參閱虛擬網路文件,特別是快速入門文章,裡面會提供逐步操作詳細資料。

    在虛擬網路設定期間,如果您使用 ExpressRoute 搭配與 Microsoft 對等互連的網路,請將下列服務端點新增至將佈建服務的子網路:

    • 目標資料庫端點 (例如,SQL 端點、Azure Cosmos DB 端點等)
    • 儲存體端點
    • 服務匯流排端點

    此為必要設定,因為 Azure 資料庫移轉服務沒有網際網路連線。

  • 請確定您虛擬網路的網路安全性群組 (NSG) 規則不會封鎖服務匯流排、儲存體和 Azure 監視器服務標籤的輸出連接埠 443。 如需虛擬網路 NSG 流量篩選的詳細資訊,請參閱<使用網路安全性群組來篩選網路流量>(機器翻譯) 一文。

  • 設定用於 Database Engine 存取的 Windows 防火牆

  • 開啟 Windows 防火牆以允許 Azure 資料庫移轉服務存取來源 PostgreSQL 伺服器,其預設會為 TCP 連接埠 5432。

  • 使用來源資料庫前面的防火牆設備時,您可能必須新增防火牆規則,才能讓 Azure 資料庫移轉服務存取來源資料庫,以進行移轉。

  • 建立適用於 PostgreSQL 的 Azure 資料庫的伺服器層級防火牆規則,以允許 Azure 資料庫移轉服務存取目標資料庫。 提供用於 Azure 資料庫移轉服務之虛擬網路的子網路範圍。

  • 叫用 CLI 有兩種方法:

    • 在 Azure 入口網站右上角,選取 [Cloud Shell] 按鈕:

      Azure 入口網站中 Cloud Shell 按鈕的螢幕擷取畫面。

    • 在本機安裝並執行 CLI。 需要 CLI 2.18 或更新版本的命令行工具,才能管理此移轉所需的 Azure 資源。

      若要下載 CLI,請依照安裝 Azure CLI 一文中的指示進行。 該文章也列出支援 Azure CLI 的平台。

      若要設定適用於 Linux 的 Windows 子系統 (WSL),請依照 Windows 10 安裝指南中的指示執行

  • 編輯 postgresql.config 檔案並設定下列參數,以在來源伺服器上啟用邏輯複寫:

    • wal_level = logical

    • max_replication_slots = [插槽數目]。 建議的設定為 5

    • max_wal_senders = [並行工作的數目]。 max_wal_senders 參數會設定可執行的並行工作數目。 建議的設定為 10

移轉範例結構描述

若要完成所有資料表物件 (例如資料表結構描述、索引和預存程序),我們必須從來源資料庫擷取結構描述,並套用至資料庫。

  1. 使用 pg_dump-s 命令來建立資料庫的結構描述傾印檔案。

    pg_dump -O -h hostname -U db_username -d db_name -s > your_schema.sql
    

    例如,若要傾印結構描述檔案 dvdrental 資料庫:

    pg_dump -O -h localhost -U postgres -d dvdrental -s  > dvdrentalSchema.sql
    

    如需有關使用 pg_dump 公用程式的詳細資訊,請參閱 pg-dump 教學課程中的範例。

  2. 在您的目標環境中建立一個空的資料庫,即適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器。

  3. 透過還原結構描述傾印檔案,將結構描述匯入到您所建立的目標資料庫中。

    psql -h hostname -U db_username -d db_name < your_schema.sql
    

    例如:

    psql -h mypgserver-20170401.postgres.database.azure.com  -U postgres -d dvdrental < dvdrentalSchema.sql
    

    注意

    移轉服務會在內部處理外部索引鍵和觸發程序的啟用/停用,以確保可靠且強固的資料移轉。 因此,您不必擔心對目標資料庫結構描述進行任何修改。

使用 Azure CLI 佈建 DMS 執行個體

  1. 安裝 DMS 同步處理延伸模組:

    • 執行下列命令以登入 Azure:

      az login
      
    • 出現提示時,請開啟網頁瀏覽器並輸入代碼,以驗證您的裝置。 依照列出的指示執行。

    • PostgreSQL 線上移轉現在可在一般 CLI 套件 (2.18.0 版和更新版本) 內使用,而不需要 dms-preview 延伸模組。 如果您過去已安裝延伸模組,可以使用下列步驟將其移除:

      • 若要檢查您是否已安裝 dms-preview 延伸模組,請執行下列命令:

        az extension list -o table
        
      • 如果已安裝 dms-preview 延伸模組,請執行下列命令來加以解除安裝:

        az extension remove --name dms-preview
        
      • 若要確認您已正確解除安裝 dms-preview 延伸模組,請執行下列命令,您在清單中應該不會看到 dms-preview 延伸模組:

        az extension list -o table
        

      重要

      Azure DMS 支援的其他移轉路徑仍可能需要 dms-preview 延伸模組。 請檢查特定移轉路徑的文件,以判斷是否需要延伸模組。 本文件涵蓋延伸模組的需求,特別是 PostgreSQL 到適用於 PostgreSQL 的 Azure 資料庫線上。

    • 隨時透過執行下列命令查看 DMS 中支援的所有命令:

      az dms -h
      
    • 如果您有多個 Azure 訂用帳戶,請執行下列命令來設定您要用來佈建 DMS 服務執行個體的訂用帳戶。

      az account set -s <SubscriptionID>
      
  2. 透過執行下列命令來佈建 DMS 執行個體:

    az dms create -l <location> -n <newServiceName> -g <yourResourceGroupName> --sku-name Premium_4vCores --subnet/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroupName>/providers/Microsoft.Network/virtualNetworks/<VirtualNetwork>/subnets/<SubnetName> –tags tagName1=tagValue1 tagWithNoValue
    

    例如,下列命令會建立服務: 以有效值取代 <SubscriptionID><ResourceGroupName><VirtualNetwork>

    • 位置:美國東部 2
    • 訂用帳戶<SubscriptionID>
    • 資源群組名稱<ResourceGroupName>
    • DMS 服務名稱PostgresCLI
    az dms create -l eastus2 -g <ResourceGroupName> -n PostgresCLI --subnet /subscriptions/<SubscriptionID>/resourceGroups/ERNetwork/providers/Microsoft.Network/virtualNetworks/<VirtualNetwork>/subnets/Subnet-1 --sku-name Premium_4vCores
    

    建立 DMS 服務執行個體需要大約 10 分鐘。

  3. 若要識別 DMS 代理程式的 IP 位址,以便將它加入 Postgres pg_hba.conf 檔案,請執行下列命令:

    az network nic list -g <ResourceGroupName> --query '[].ipConfigurations | [].privateIpAddress'
    

    例如:

    az network nic list -g <resource-group> --query '[].ipConfigurations | [].privateIpAddress'
    

    您應該會取得類似下列位址的結果:

    [
      "172.16.136.18"
    ]
    
  4. 將 DMS 代理程式的 IP 位址加入 Postgres pg_hba.conf 檔案中。

    • 在 DMS 中完成佈建後,請記下 DMS IP 位址。

    • 將 IP 位址加入到來源上的 pg_hba.conf 檔案中,類似於下列項目:

      host     all            all        172.16.136.18/10    md5
      host     replication    postgres   172.16.136.18/10    md5
      
  5. 接下來,執行下列命令來建立 PostgreSQL 移轉專案:

    az dms project create -l <location> -g <ResourceGroupName> --service-name <yourServiceName> --source-platform PostgreSQL --target-platform AzureDbforPostgreSQL -n <newProjectName>
    

    例如,下列命令會使用這些參數建立專案:

    • 位置:美國中西部
    • 資源群組名稱<ResourceGroupName>
    • 服務名稱:PostgresCLI
    • 專案名稱:PGMigration
    • 來源平台:PostgreSQL
    • 目標平台:AzureDbForPostgreSql
    az dms project create -l westcentralus -n PGMigration -g <ResourceGroupName> --service-name PostgresCLI --source-platform PostgreSQL --target-platform AzureDbForPostgreSql
    
  6. 使用下列步驟建立 PostgreSQL 移轉工作。

    此步驟包括使用來源 IP、使用者識別碼與密碼、目的地 IP、使用者識別碼、密碼與工作類型來建立連線。

    • 若要查看完整的選項清單,請執行命令:

      az dms project task create -h
      

      針對來源與目標連線,輸入參數指的是具有物件清單的 json 檔案。

      適用於 PostgreSQL 連線的連線 JSON 物件格式。

      {
          // if this is missing or null, you will be prompted
          "userName": "user name",
          // if this is missing or null (highly recommended) you will  be prompted
          "password": null,
          "serverName": "server name",
          // if this is missing, it will default to the 'postgres' database
          "databaseName": "database name",
          // if this is missing, it will default to 5432
          "port": 5432
      }
      

      還有一個列出 json 物件的資料庫選項 json 檔案。 針對 PostgreSQL,資料庫選項 JSON 物件的格式如下所示:

      [
          {
              "name": "source database",
              "target_database_name": "target database",
              "selectedTables": [
                  "schemaName1.tableName1",
                  ...n
              ]
          },
          ...n
      ]
      
    • 若要建立來源連線 json,請開啟 [記事本],然後複製下列 json 並貼到檔案中。 根據來源伺服器修改檔案之後,請將檔案儲存在 C:\DMS\source.json 中。

      {
          "userName": "postgres",
          "password": null,
          "serverName": "13.51.14.222",
          "databaseName": "dvdrental",
          "port": 5432
      }
      
    • 若要建立目標連線 json,請開啟 [記事本],然後複製下列 json 並貼到檔案中。 根據目標伺服器修改檔案之後,請將檔案儲存在 C:\DMS\target.json 中。

      {
          "userName": " dms@builddemotarget",
          "password": null,
          "serverName": " builddemotarget.postgres.database.azure.com",
          "databaseName": "inventory",
          "port": 5432
      }
      
    • 建立一個資料庫選項 json 檔案,其中列出詳細目錄和所要遷移資料庫的對應:

      • 建立所要遷移資料表的清單,或使用 SQL 查詢從來源資料庫產生清單。 以下是產生資料表清單的範例查詢。 如果使用此查詢,記得移除最後一個資料表結尾的最後一個逗號,使其成為有效的 JSON 陣列。

        SELECT FORMAT('%s,', REPLACE(FORMAT('%I.%I', schemaname, tablename), '"', '\"')) AS SelectedTables
        FROM pg_tables
        WHERE schemaname NOT IN ('pg_catalog', 'information_schema');
        
      • 建立資料庫選項 JSON 檔案,其中包含每一個項目各一個資料庫 (來源和目標資料庫名稱),以及所要遷移的所選資料表清單。 您可以使用之前 SQL 查詢的輸出來填入 selectedTables 陣列。

        注意

        如果選取的資料表清單是空的,則服務會包含具有相符結構描述和資料表名稱的所有移轉資料表。

        [
            {
                "name": "dvdrental",
                "target_database_name": "dvdrental",
                "selectedTables": [
                    "schemaName1.tableName1",
                    "schemaName1.tableName2",
                    ...
                    "schemaNameN.tableNameM"
                ]
            },
            ... n
        ]
        
    • 執行下列命令,其會接受來源連線、目標連線和資料庫選項 json 檔案。

      az dms project task create -g <ResourceGroupName> --project-name PGMigration --source-connection-json c:\DMS\source.json --database-options-json C:\DMS\option.json --service-name PostgresCLI --target-connection-json c:\DMS\target.json --task-type OnlineMigration -n runnowtask
      

    此時,您已成功送出移轉工作。

  7. 若要顯示工作的進度,請執行下列命令。

    • 若要查看簡短的一般工作狀態:

      az dms project task show --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask
      
    • 若要查看詳細的工作狀態,包括移轉進度資訊:

      az dms project task show --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask --expand output
      
    • 您也可以使用 JMESPath 查詢格式,僅從展開輸出擷取 migrationState

      az dms project task show --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask --expand output --query 'properties.output[].migrationState'
      

      在輸出中,有幾個參數表示不同移轉步驟的進度。 例如,請看下列的輸出:

      {
          "output": [
              // Database Level
              {
                  "appliedChanges": 0, // Total incremental sync applied after full load
                  "cdcDeleteCounter": 0, // Total delete operation  applied after full load
                  "cdcInsertCounter": 0, // Total insert operation applied after full load
                  "cdcUpdateCounter": 0, // Total update operation applied after full load
                  "databaseName": "inventory",
                  "endedOn": null,
                  "fullLoadCompletedTables": 2, //Number of tables completed full load
                  "fullLoadErroredTables": 0, //Number of tables that contain migration error
                  "fullLoadLoadingTables": 0, //Number of tables that are in loading status
                  "fullLoadQueuedTables": 0, //Number of tables that are in queued status
                  "id": "db|inventory",
                  "incomingChanges": 0, //Number of changes after full load
                  "initializationCompleted": true,
                  "latency": 0,
                  //Status of migration task
                  "migrationState": "READY_TO_COMPLETE", //READY_TO_COMPLETE => the database is ready for cutover
                  "resultType": "DatabaseLevelOutput",
                  "startedOn": "2018-07-05T23:36:02.27839+00:00"
              }, {
                  "databaseCount": 1,
                  "endedOn": null,
                  "id": "dd27aa3a-ed71-4bff-ab34-77db4261101c",
                  "resultType": "MigrationLevelOutput",
                  "sourceServer": "138.91.123.10",
                  "sourceVersion": "PostgreSQL",
                  "startedOn": "2018-07-05T23:36:02.27839+00:00",
                  "state": "PENDING",
                  "targetServer": "builddemotarget.postgres.database.azure.com",
                  "targetVersion": "Azure Database for PostgreSQL"
              },
              // Table 1
              {
                  "cdcDeleteCounter": 0,
                  "cdcInsertCounter": 0,
                  "cdcUpdateCounter": 0,
                  "dataErrorsCount": 0,
                  "databaseName": "inventory",
                  "fullLoadEndedOn": "2018-07-05T23:36:20.740701+00:00", //Full load completed time
                  "fullLoadEstFinishTime": "1970-01-01T00:00:00+00:00",
                  "fullLoadStartedOn": "2018-07-05T23:36:15.864552+00:00", //Full load started time
                  "fullLoadTotalRows": 10, //Number of rows loaded in full load
                  "fullLoadTotalVolumeBytes": 7056, //Volume in Bytes in full load
                  "id": "or|inventory|public|actor",
                  "lastModifiedTime": "2018-07-05T23:36:16.880174+00:00",
                  "resultType": "TableLevelOutput",
                  "state": "COMPLETED", //State of migration for this table
                  "tableName": "public.catalog", //Table name
                  "totalChangesApplied": 0 //Total sync changes that applied after full load
              },
              //Table 2
              {
                  "cdcDeleteCounter": 0,
                  "cdcInsertCounter": 50,
                  "cdcUpdateCounter": 0,
                  "dataErrorsCount": 0,
                  "databaseName": "inventory",
                  "fullLoadEndedOn": "2018-07-05T23:36:23.963138+00:00",
                  "fullLoadEstFinishTime": "1970-01-01T00:00:00+00:00",
                  "fullLoadStartedOn": "2018-07-05T23:36:19.302013+00:00",
                  "fullLoadTotalRows": 112,
                  "fullLoadTotalVolumeBytes": 46592,
                  "id": "or|inventory|public|address",
                  "lastModifiedTime": "2018-07-05T23:36:20.308646+00:00",
                  "resultType": "TableLevelOutput",
                  "state": "COMPLETED",
                  "tableName": "public.orders",
                  "totalChangesApplied": 0
              }
          ],
          // DMS migration task state
          "state": "Running", //Running => service is still listening to any changes that might come in
          "taskType": null
      }
      

完全移轉工作

完整載入完成後,資料庫準備好進行完全移轉。 根據來源伺服器處理新交易的忙碌程度,DMS 工作可能仍會在完整載入完成後套用變更。

若要確保擷取所有資料,請驗證來源與目標資料庫之間的資料列計數。 例如,您可以從狀態輸出驗證下列詳細資料:

Database Level
"migrationState": "READY_TO_COMPLETE" => Status of migration task. READY_TO_COMPLETE means database is ready for cutover
"incomingChanges": 0 => Check for a period of 5-10 minutes to ensure no new incoming changes need to be applied to the target server

Table Level (for each table)
"fullLoadTotalRows": 10    => The row count matches the initial row count of the table
"cdcDeleteCounter": 0      => Number of deletes after the full load
"cdcInsertCounter": 50     => Number of inserts after the full load
"cdcUpdateCounter": 0      => Number of updates after the full load
  1. 使用下列命令,執行完全移轉資料庫移轉工作:

    az dms project task cutover -h
    

    例如,下列命令會起始 'Inventory' 資料庫的者完全移轉:

    az dms project task cutover --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask  --object-name Inventory
    
  2. 若要監視移轉進度,請執行下列命令:

    az dms project task show --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask
    
  3. 當資料庫移轉狀態顯示 [已完成] 時,請重新建立序列 (如果適用),然後將應用程式連線至適用於 PostgreSQL 的 Azure 資料庫的新目標執行個體。

服務、專案、工作清除

如果您要取消或刪除任何 DMS 工作、專案或服務,請依照以下順序取消:

  • 取消任何執行中的工作
  • 刪除工作
  • 刪除專案
  • 刪除 DMS 服務
  1. 若要取消執行中的工作,請使用下列命令:

    az dms project task cancel --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask
    
  2. 若要刪除執行中的工作,請使用下列命令:

    az dms project task delete --service-name PostgresCLI --project-name PGMigration --resource-group <ResourceGroupName> --name runnowtask
    
  3. 若要刪除專案,請使用下列命令:

    az dms project delete -n PGMigration -g <ResourceGroupName> --service-name PostgresCLI
    
  4. 若要刪除 DMS 服務,請使用下列命令:

    az dms delete -g <ResourceGroupName> -n PostgresCLI