练习:将本地 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 灵活服务器
使用 Web 浏览器打开新选项卡并导航到 Azure 门户。
在搜索栏中,键入 Azure Database for PostgreSQL 弹性服务器。
在Azure Database for PostgreSQL 弹性服务器页上,选择“+ 创建”。
在 “灵活服务器 ”页上,输入以下详细信息,然后选择“ 查看 + 创建” :
财产 价值 资源组 migrate-postgresql 服务器名称 adventureworksnnn,其中 nnn 是所选的后缀,用于使该服务器名称成为唯一名称 位置 选择最近的位置 PostgreSQL 版本 13 计算 + 存储 依次选择“配置服务器”、“基本”定价层和“确定” 管理员用户名 awadmin 密码 Pa55w.rdDemo 确认密码 Pa55w.rdDemo 在“查看 + 创建”页面上,选择“创建”。 等待服务创建完毕,然后再继续操作。
创建服务后,选择“转到资源”。
选择“连接安全性”。
在“连接安全性”页面上,将“允许访问 Azure 服务”设置为“是”。
在防火墙规则列表中,添加名为 VM 的规则,并将 START IP 地址 和 结束 IP 地址 设置为运行前面创建的 PostgreSQL 服务器的虚拟机的 IP 地址。
选择 “添加当前客户端 IP 地址”,使客户端计算机能够连接到数据库。
单击“保存”,然后等待防火墙规则更新完成。
在 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,以导出数据库架构。
运行以下 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
使用 SSH 连接到旧的数据库服务器。 输入“Pa55w.rdDemo”作为密码。
ssh azureuser@$SQLIP
运行以下命令以连接到虚拟机上的数据库。 在虚拟机上运行的 PostgreSQL 服务器中 azureuser 用户的密码为 Pa55w.rd:
psql adventureworks
向 azureuser 授予复制权限:
ALTER ROLE azureuser REPLICATION;
使用 \q 命令关闭 psql 实用工具。
在 bash 提示符下运行以下命令,将 adventureworks 数据库的架构导出到名为 adventureworks_schema.sql 的文件中。
pg_dump -o -d adventureworks -s > adventureworks_schema.sql
将架构导入到目标数据库
运行以下命令以连接到 azureadventureworks[nnn] 服务器。 将两个实例的 [nnn] 替换为服务的后缀。 请注意,用户名具有 @adventureworks[nnn] 后缀。 在密码提示符下,输入 Pa55w.rdDemo。
psql -h adventureworks[nnn].postgres.database.azure.com -U awadmin@adventureworks[nnn] -d postgres
运行以下命令创建一位名为“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;
使用 \q 命令关闭 psql 实用工具。
将 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
创建每个项目时,将看到一系列消息。 脚本应完成且没有任何错误。
运行以下命令。 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
运行以下命令。 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
运行 dropkeys.sql 脚本:
psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks -f dropkeys.sql
删除外键时,将显示一系列“ALTER TABLE”消息。
再次启动 psql 实用工具并连接到 azureadventureworks 数据库。
psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks
运行以下查询,查找任何剩余外键的详细信息:
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];
删除所有剩余的外键后,执行以下 SQL 语句以显示数据库中的触发器:
SELECT trigger_name FROM information_schema.triggers;
此查询还应返回一个空的结果集,指示数据库不包含任何触发器。 如果数据库确实包含触发器,则必须在迁移数据之前禁用它们,然后重新启用它们。
使用 \q 命令关闭 psql 实用工具。
使用数据库迁移服务执行联机迁移
切换回 Azure 门户。
选择 “所有服务”,选择“ 订阅”,然后选择你的订阅。
在“订阅”页的“设置”下,选择“资源提供程序”。
在“按名称筛选”框中,键入“DataMigration”,然后选择“Microsoft.DataMigration”。
如果未注册 Microsoft.DataMigration ,请选择“ 注册”,然后等待 状态 更改为 “已注册”。 可能需要选择“ 刷新 ”以查看状态更改。
选择“创建资源”,在“搜索市场”框中键入“Azure 数据库迁移服务”,然后按 Enter。
在“Azure 数据库迁移服务”页上,选择“创建”。
在 “创建迁移服务 ”页上,输入以下详细信息,然后选择“ 下一步:网络>>”。
财产 价值 选择资源组 migrate-postgresql 服务名称 adventureworks_migration_service 位置 选择最近的位置 服务模式 天蓝色 定价等级 高级,带有 4 个 vCore 在 “网络 ”页上,选择 postgresqlvnet/posgresqlvmSubnet 虚拟网络。 此网络是在设置过程中创建的。
选择“查看 + 创建”,然后选择“创建” 。 等待数据库迁移服务创建完成。 这需要几分钟时间。
创建服务后,选择“转到资源”。
选择“新建迁移项目”。
在“新建迁移项目”页面上,输入以下详细信息,然后选择“创建并运行活动”。
财产 价值 项目名称 adventureworks_migration_project 源服务器类型 PostgreSQL 目标 Database for PostgreSQL Azure Database for PostgreSQL 选择活动类型 联机数据迁移 迁移向导启动时,在“选择源”页上输入以下详细信息,然后选择“下一步:选择目标>>”。
财产 价值 源服务器名称 nn.nn.nn.nn (运行 PostgreSQL 的 Azure 虚拟机的 IP 地址) 服务器端口 5432 数据库 adventureworks 用户名 azureuser 密码 Pa55w.rd 信任服务器证书 已选择 加密连接 已选择 在 “选择目标 ”页上,输入以下详细信息,然后选择“ 下一步:选择数据库>>”。
财产 价值 Azure PostgreSQL adventureworks[nnn] 数据库 azureadventureworks 用户名 azureuser@adventureworks[nnn] 密码 Pa55w.rd 在 “选择数据库 ”页上,选择 adventureworks 数据库并将其映射到 azureadventureworks。 取消勾选 postgres 数据库。 选择 “下一步:选择表>>”。
在“ 选择表 ”页上,选择“ 下一步:配置迁移设置>>”。
在“ 配置迁移设置 ”页上,展开 adventureworks 下拉列表,展开 “高级联机迁移设置”下拉列表,验证 并行加载的最大实例数 是否设置为 5,然后选择“ 下一步:摘要>>”。
在 “摘要 ”页上,在 “活动名称 ”框中键入 AdventureWorks_Migration_Activity,然后选择“ 开始迁移”。
在“AdventureWorks_Migration_Activity”页面上,每隔 15 秒选择一次“刷新”。 在迁移作进行时,你将看到迁移作的状态。 等待“迁移详细信息”列更改为“可直接转换”。
切换回 Cloud Shell。
运行以下命令,在 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 的目标数据库中手动恢复此约束。
不应出现其他错误。
修改数据,并切换到新数据库
返回到 Azure 门户中的“AdventureWorks_Migration_Activity”页面。
选择 adventureworks 数据库。
在 adventureworks 页上,验证 “完全加载已完成 ”值是否为 66 ,并且所有其他值均为 0。
切换回 Cloud Shell。
运行以下命令以连接到在虚拟机上使用 PostgreSQL 运行的 adventureworks 数据库:
psql adventureworks
执行以下 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);
使用 \q 命令关闭 psql 实用工具。
返回到 Azure 门户中的 adventureworks 页,然后选择“ 刷新”。 验证是否已应用 32 个更改。
选择“启动直接转换”。
在“完成直接转换”页上,选择“确认”,然后选择“应用”。 等待状态更改为“已完成”。
退回到 Cloud Shell。
运行以下命令,连接到使用 Azure Database for PostgreSQL 服务运行的 azureadventureworks 数据库:
psql -h adventureworks[nnn].postgres.database.azure.com -U azureuser@adventureworks[nnn] -d azureadventureworks
密码为 Pa55w.rd。
执行以下 SQL 语句以显示数据库中的订单和订单详细信息。 在每个表的第一页之后退出。 这些查询的目的是显示已传输数据:
SELECT * FROM sales.salesorderheader; SELECT * FROM sales.salesorderdetail;
运行以下 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 行。
使用 \q 命令关闭 psql 实用工具。
清理已创建的资源
重要
如果你已在自己的个人订阅中执行了这些步骤,则可以分别删除资源或删除资源组以删除整个资源集。 剩余运行的资源可能会花费你钱。
- 使用 Cloud Shell 运行此命令,以删除资源组:
az group delete --name migrate-postgresql