练习:将本地 PostgreSQL 数据库迁移到 Azure Database for PostgreSQL

已完成

在本练习中,你将 PostgreSQL 数据库迁移到 Azure。 将虚拟机上运行的现有 PostgreSQL 数据库迁移到 Azure Database for PostgreSQL。

你是 AdventureWorks 组织中的一名数据库开发人员。 十多年来,AdventureWorks 始终直接向最终消费者和分销商销售自行车和自行车零件。 他们的系统将信息存储在当前使用 PostgreSQL 在 Azure VM 上运行的数据库中。 在实现硬件合理化的过程中,AdventureWorks 想要将该数据库移动到 Azure 托管的数据库。 组织要求你执行此迁移。

重要

免费的 Azure 沙盒环境不支持 Azure 数据迁移服务。 你可在自己的个人订阅中执行下列步骤,也可按照步骤了解如何迁移数据库。

设置环境

在 Cloud Shell 中运行这些 Azure CLI 命令,使用 adventureworks 数据库的副本创建运行 PostgreSQL 的虚拟机。 最后一个命令将打印新虚拟机的 IP 地址。

az account list-locations -o table

az group create \
    --name migrate-postgresql \
    --___location <CHOOSE A LOCATION FROM ABOVE NEAR YOU>

az vm create \
    --resource-group migrate-postgresql \
    --name postgresqlvm \
    --admin-username azureuser \
    --admin-password Pa55w.rdDemo \
    --image Ubuntu2204 \
    --public-ip-address-allocation static \
    --public-ip-sku Standard \
    --vnet-name postgresqlvnet \
    --nsg ""

az vm run-command invoke \
    --resource-group migrate-postgresql \
    --name postgresqlvm \
    --command-id RunShellScript \
    --scripts "
# Install PostgreSQL
sudo echo deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main > /etc/apt/sources.list.d/pgdg.list
sudo wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get -y update
sudo apt-get -y install postgresql-10
# Clone exercise code
sudo git clone https://github.com/MicrosoftLearning/DP-070-Migrate-Open-Source-Workloads-to-Azure.git /home/azureuser/workshop    
# Configure PostgreSQL
sudo service postgresql stop
sudo bash << EOF
    printf \"listen_addresses = '*'\nwal_level = logical\nmax_replication_slots = 5\nmax_wal_senders = 10\n\" >> /etc/postgresql/10/main/postgresql.conf
    printf \"host    all             all             0.0.0.0/0               md5\n\" >> /etc/postgresql/10/main/pg_hba.conf
EOF
sudo service postgresql start

# Add the azureuser role and adventure works
sudo bash << EOF
su postgres << EOC
printf \"create role azureuser with login;alter role azureuser createdb;alter role azureuser password 'Pa55w.rd';alter role azureuser superuser;create database adventureworks;grant all privileges on database adventureworks to azureuser; \" | psql
EOC
EOF

PGPASSWORD=Pa55w.rd psql -h localhost -U azureuser adventureworks -E -q -f /home/azureuser/workshop/migration_samples/setup/postgresql/adventureworks/adventureworks.sql
"

az vm open-port \
    --resource-group migrate-postgresql \
    --name postgresqlvm \
    --priority 200 \
    --port '22'

az vm open-port \
    --resource-group migrate-postgresql \
    --name postgresqlvm \
    --priority 300 \
    --port '5432'

echo Setup Complete

SQLIP="$(az vm list-ip-addresses \
    --resource-group migrate-postgresql \
    --name postgresqlvm \
    --query "[].virtualMachine.network.publicIpAddresses[*].ipAddress" \
    --output tsv)"

echo $SQLIP

这些命令大约需要 5 分钟才能完成。 无需等待,你可继续执行下面的步骤。

创建 Azure Database for PostgreSQL 灵活服务器

  1. 使用 Web 浏览器打开新选项卡并导航到 Azure 门户

  2. 在搜索栏中,键入 Azure Database for PostgreSQL 弹性服务器

  3. Azure Database for PostgreSQL 弹性服务器页上,选择“+ 创建”。

  4. “灵活服务器 ”页上,输入以下详细信息,然后选择“ 查看 + 创建” :

    财产 价值
    资源组 migrate-postgresql
    服务器名称 adventureworksnnn,其中 nnn 是所选的后缀,用于使该服务器名称成为唯一名称
    位置 选择最近的位置
    PostgreSQL 版本 13
    计算 + 存储 依次选择“配置服务器”、“基本”定价层和“确定”
    管理员用户名 awadmin
    密码 Pa55w.rdDemo
    确认密码 Pa55w.rdDemo
  5. 在“查看 + 创建”页面上,选择“创建”。 等待服务创建完毕,然后再继续操作。

  6. 创建服务后,选择“转到资源”。

  7. 选择“连接安全性”。

  8. 在“连接安全性”页面上,将“允许访问 Azure 服务”设置为“是”。

  9. 在防火墙规则列表中,添加名为 VM 的规则,并将 START IP 地址结束 IP 地址 设置为运行前面创建的 PostgreSQL 服务器的虚拟机的 IP 地址。

  10. 选择 “添加当前客户端 IP 地址”,使客户端计算机能够连接到数据库。

  11. 单击“保存”,然后等待防火墙规则更新完成。

  12. 在 Cloud Shell 提示符下运行以下命令,在 Azure Database for PostgreSQL 服务中创建新数据库。 将 [nnn] 替换为创建 Azure Database for PostgreSQL 服务时使用的后缀。 将 [resource group] 替换为你为服务指定的资源组的名称:

    az postgres flexible-server create \
      --name azureadventureworks \
      --resource-group migrate-postgresql
    

    如果数据库创建成功,应会看到如下所示的消息:

    {
      "charset": "UTF8",
      "collation": "English_United States.1252",
      "name": "azureadventureworks",
      "resourceGroup": "migrate-postgresql",
      "type": "Microsoft.DBforPostgreSQL/servers/databases"
    }
    

导出要在目标数据库上使用的架构

现在,你将使用 Cloud Shell 连接到现有的 PostgreSQL VM,以导出数据库架构。

  1. 运行以下 Azure CLI 命令可查看现有 VM 的 IP 地址。

    SQLIP="$(az vm list-ip-addresses \
        --resource-group migrate-postgresql \
        --name postgresqlvm \
        --query "[].virtualMachine.network.publicIpAddresses[*].ipAddress" \
        --output tsv)"
    
    echo $SQLIP
    
  2. 使用 SSH 连接到旧的数据库服务器。 输入“Pa55w.rdDemo”作为密码。

    ssh azureuser@$SQLIP
    
  3. 运行以下命令以连接到虚拟机上的数据库。 在虚拟机上运行的 PostgreSQL 服务器中 azureuser 用户的密码为 Pa55w.rd

    psql adventureworks
    
  4. 向 azureuser 授予复制权限:

    ALTER ROLE azureuser REPLICATION;
    
  5. 使用 \q 命令关闭 psql 实用工具。

  6. 在 bash 提示符下运行以下命令,将 adventureworks 数据库的架构导出到名为 adventureworks_schema.sql 的文件中。

    pg_dump -o  -d adventureworks -s > adventureworks_schema.sql
    

将架构导入到目标数据库

  1. 运行以下命令以连接到 azureadventureworks[nnn] 服务器。 将两个实例的 [nnn] 替换为服务的后缀。 请注意,用户名具有 @adventureworks[nnn] 后缀。 在密码提示符下,输入 Pa55w.rdDemo。

    psql -h adventureworks[nnn].postgres.database.azure.com -U awadmin@adventureworks[nnn] -d postgres
    
  2. 运行以下命令创建一位名为“azureuser”的用户,并将该用户的密码设置为“Pa55w.rd”。 第三个语句为 azureuser 用户提供在 azureadventureworks 数据库中创建和管理对象所需的特权。 azure_pg_admin角色使 azureuser 用户能够在数据库中安装和使用扩展。

    CREATE ROLE azureuser WITH LOGIN;
    ALTER ROLE azureuser PASSWORD 'Pa55w.rd';
    GRANT ALL PRIVILEGES ON DATABASE azureadventureworks TO azureuser;
    GRANT azure_pg_admin TO azureuser;
    
  3. 使用 \q 命令关闭 psql 实用工具。

  4. adventureworks 数据库的架构导入 Azure Database for PostgreSQL 服务上运行的 azureadventureworks 数据库。 你将以 azureuser 身份执行导入,因此在出现提示时,请输入密码 Pa55w.rd。

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks -E -q -f adventureworks_schema.sql
    

    创建每个项目时,将看到一系列消息。 脚本应完成且没有任何错误。

  5. 运行以下命令。 findkeys.sql脚本生成另一个名为dropkeys.sql的 SQL 脚本,该脚本将从 azureadventureworks 数据库中的表中删除所有外键。 稍后将运行 dropkeys.sql 脚本:

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks -f workshop/migration_samples/setup/postgresql/adventureworks/findkeys.sql -o dropkeys.sql -t
    
  6. 运行以下命令。 createkeys.sql脚本生成另一个名为addkeys.sql的 SQL 脚本,该脚本将重新创建所有外键。 迁移数据库后,将运行 addkeys.sql 脚本:

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks -f workshop/migration_samples/setup/postgresql/adventureworks/createkeys.sql -o addkeys.sql -t
    
  7. 运行 dropkeys.sql 脚本:

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks -f dropkeys.sql
    

    删除外键时,将显示一系列“ALTER TABLE”消息

  8. 再次启动 psql 实用工具并连接到 azureadventureworks 数据库。

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks
    
  9. 运行以下查询,查找任何剩余外键的详细信息:

    SELECT constraint_type, table_schema, table_name, constraint_name
    FROM information_schema.table_constraints
    WHERE constraint_type = 'FOREIGN KEY';
    

    此查询应返回空的结果集。 但是,如果任何外键仍然存在,则对于每个外键,请运行以下命令:

    ALTER TABLE [table_schema].[table_name] DROP CONSTRAINT [constraint_name];
    
  10. 删除所有剩余的外键后,执行以下 SQL 语句以显示数据库中的触发器:

    SELECT trigger_name
    FROM information_schema.triggers;
    

    此查询还应返回一个空的结果集,指示数据库不包含任何触发器。 如果数据库确实包含触发器,则必须在迁移数据之前禁用它们,然后重新启用它们。

  11. 使用 \q 命令关闭 psql 实用工具。

使用数据库迁移服务执行联机迁移

  1. 切换回 Azure 门户。

  2. 选择 “所有服务”,选择“ 订阅”,然后选择你的订阅。

  3. 在“订阅”页的“设置”下,选择“资源提供程序”。

  4. 在“按名称筛选”框中,键入“DataMigration”,然后选择“Microsoft.DataMigration”。

  5. 如果未注册 Microsoft.DataMigration ,请选择“ 注册”,然后等待 状态 更改为 “已注册”。 可能需要选择“ 刷新 ”以查看状态更改。

  6. 选择“创建资源”,在“搜索市场”框中键入“Azure 数据库迁移服务”,然后按 Enter。

  7. 在“Azure 数据库迁移服务”页上,选择“创建”。

  8. “创建迁移服务 ”页上,输入以下详细信息,然后选择“ 下一步:网络>>”。

    财产 价值
    选择资源组 migrate-postgresql
    服务名称 adventureworks_migration_service
    位置 选择最近的位置
    服务模式 天蓝色
    定价等级 高级,带有 4 个 vCore
  9. “网络 ”页上,选择 postgresqlvnet/posgresqlvmSubnet 虚拟网络。 此网络是在设置过程中创建的。

  10. 选择“查看 + 创建”,然后选择“创建” 。 等待数据库迁移服务创建完成。 这需要几分钟时间。

  11. 创建服务后,选择“转到资源”。

  12. 选择“新建迁移项目”。

  13. 在“新建迁移项目”页面上,输入以下详细信息,然后选择“创建并运行活动”。

    财产 价值
    项目名称 adventureworks_migration_project
    源服务器类型 PostgreSQL
    目标 Database for PostgreSQL Azure Database for PostgreSQL
    选择活动类型 联机数据迁移
  14. 迁移向导启动时,在“选择源”页上输入以下详细信息,然后选择“下一步:选择目标>>”。

    财产 价值
    源服务器名称 nn.nn.nn.nn (运行 PostgreSQL 的 Azure 虚拟机的 IP 地址)
    服务器端口 5432
    数据库 adventureworks
    用户名 azureuser
    密码 Pa55w.rd
    信任服务器证书 已选择
    加密连接 已选择
  15. “选择目标 ”页上,输入以下详细信息,然后选择“ 下一步:选择数据库>>”。

    财产 价值
    Azure PostgreSQL adventureworks[nnn]
    数据库 azureadventureworks
    用户名 azureuser@adventureworks[nnn]
    密码 Pa55w.rd
  16. “选择数据库 ”页上,选择 adventureworks 数据库并将其映射到 azureadventureworks。 取消勾选 postgres 数据库。 选择 “下一步:选择表>>”。

  17. 在“ 选择表 ”页上,选择“ 下一步:配置迁移设置>>”。

  18. 在“ 配置迁移设置 ”页上,展开 adventureworks 下拉列表,展开 “高级联机迁移设置”下拉列表,验证 并行加载的最大实例数 是否设置为 5,然后选择“ 下一步:摘要>>”。

  19. “摘要 ”页上,在 “活动名称 ”框中键入 AdventureWorks_Migration_Activity,然后选择“ 开始迁移”。

  20. 在“AdventureWorks_Migration_Activity”页面上,每隔 15 秒选择一次“刷新”。 在迁移作进行时,你将看到迁移作的状态。 等待“迁移详细信息”列更改为“可直接转换”。

  21. 切换回 Cloud Shell。

  22. 运行以下命令,在 azureadventureworks 数据库中重新创建外键。 之前已生成 addkeys.sql 脚本:

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks -f addkeys.sql
    

    添加外键时,会看到一系列 ALTER TABLE 语句。 你可能会看到有关 SpecialOfferProduct 表的错误,现在可以忽略该表。 这是因为唯一约束无法正确传输。 在现实世界中,应使用以下查询从源数据库中检索此约束的详细信息:

    SELECT constraint_type, table_schema, table_name, constraint_name
    FROM information_schema.table_constraints
    WHERE constraint_type = 'UNIQUE';
    

    然后,可以在 Azure Database for PostgreSQL 的目标数据库中手动恢复此约束。

    不应出现其他错误。

修改数据,并切换到新数据库

  1. 返回到 Azure 门户中的“AdventureWorks_Migration_Activity”页面。

  2. 选择 adventureworks 数据库。

  3. adventureworks 页上,验证 “完全加载已完成 ”值是否为 66 ,并且所有其他值均为 0

  4. 切换回 Cloud Shell。

  5. 运行以下命令以连接到在虚拟机上使用 PostgreSQL 运行的 adventureworks 数据库:

    psql adventureworks
    
  6. 执行以下 SQL 语句,来显示订单 43659、43660 和 43661,然后将这些订单从数据库中删除。 请注意,数据库在 salesorderheader 表上实现级联删除,该表会自动从 salesorderdetail 表中删除相应的行。

    SELECT * FROM sales.salesorderheader WHERE salesorderid IN (43659, 43660, 43661);
    SELECT * FROM sales.salesorderdetail WHERE salesorderid IN (43659, 43660, 43661);
    DELETE FROM sales.salesorderheader WHERE salesorderid IN (43659, 43660, 43661);
    
  7. 使用 \q 命令关闭 psql 实用工具。

  8. 返回到 Azure 门户中的 adventureworks 页,然后选择“ 刷新”。 验证是否已应用 32 个更改。

  9. 选择“启动直接转换”

  10. 在“完成直接转换”页上,选择“确认”,然后选择“应用”。 等待状态更改为“已完成”。

  11. 退回到 Cloud Shell。

  12. 运行以下命令,连接到使用 Azure Database for PostgreSQL 服务运行的 azureadventureworks 数据库:

    psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks
    

    密码为 Pa55w.rd

  13. 执行以下 SQL 语句以显示数据库中的订单和订单详细信息。 在每个表的第一页之后退出。 这些查询的目的是显示已传输数据:

    SELECT * FROM sales.salesorderheader;
    SELECT * FROM sales.salesorderdetail;
    
  14. 运行以下 SQL 语句,显示订单以及订单 43659、43660 和 43661 的详细信息。

    SELECT * FROM sales.salesorderheader WHERE salesorderid IN (43659, 43660, 43661);
    SELECT * FROM sales.salesorderdetail WHERE salesorderid IN (43659, 43660, 43661);
    

    这两个查询应返回 0 行。

  15. 使用 \q 命令关闭 psql 实用工具。

清理已创建的资源

重要

如果你已在自己的个人订阅中执行了这些步骤,则可以分别删除资源或删除资源组以删除整个资源集。 剩余运行的资源可能会花费你钱。

  1. 使用 Cloud Shell 运行此命令,以删除资源组:
az group delete --name migrate-postgresql