【问题标题】:Cross Subscription Copying of Databases on Windows Azure SQL DatabaseWindows Azure SQL 数据库上的数据库交叉订阅复制
【发布时间】:2020-05-07 09:30:08
【问题描述】:

我们即将将 Windows Azure 中的测试和生产实例拆分为两个单独的订阅。目前,我们有 3 个 Windows Azure SQL 数据库实例驻留在同一个订阅中:

  • 生产
  • 报告
  • 测试

为了完全隔离生产,我们将它们分为:

  • 生产订阅
    • 生产
    • 报告
  • 测试订阅
    • 测试

目前,我们使用CREATE DATABASE X AS COPY OF [ServerName].Y 命令将数据库从生产复制到测试,然后再混淆实时数据。只要数据库的地理位置位于相同的数据中心,并且我们在最初创建数据库的实例之间拥有共享登录,就可以执行此操作(As indicated by this article)。

但是;文章没有说明源实例和目标实例是否需要属于同一个订阅。假设我们使用一致的登录,我们是否能够在生产订阅和测试订阅(以及 vica verca)之间复制数据库?

【问题讨论】:

  • 对于您编写此问题所花费的时间,您将进行测试。我不知道答案,但我确信您可以在订阅之间移动 Azure SQL 数据库服务器。这可能是最糟糕的情况 - 将 Server 从 Sub-1 移动到 Sub-2,复制数据库,然后将 Server 移动回 Sub-1。在订阅之间移动数据库服务器不应引起任何停机,因为这只是一个逻辑操作。但是我不确定每个计费周期可以移动服务器的次数是否有限制。
  • "你花时间写这个问题你会测试。"对不起,我不明白这个回复;如果您被指示我们可以测试它是否可能,我们仍然只有一个订阅,这是我想在我们拆分订阅之前澄清的事情。关于移动服务器;在订阅之间移动整个实例似乎过分。特别是如果目标是分离环境。

标签: azure azure-sql-database


【解决方案1】:

对于登陆这里的任何人,确实似乎可以使用CREATE DATABASE newDB AS COPY OF [server].[olddb] ( OPTION [, OPTION ...] ),即使服务器处于不同的订阅中。

Create Database (Azure SQL Database) - MSDN查看更多信息

来自MS Docs的示例:

CREATE DATABASE db_copy AS COPY OF ozabzw7545.db_original ( SERVICE_OBJECTIVE = 'P2' ) ;

在我的设置中,我在两台服务器上的管理员帐户和密码(登录名)相同 - 这可能会有所帮助。 如果您在原始服务器上没有管理员权限,操作将失败。

我通过测试发现,尽管包含“版本”选项,但我无法将版本从标准更改为高级 - 我不确定为什么会这样。

【讨论】:

  • 很好的回复谢谢理查德;有人假设这仅限于单个数据中心?版本标志是一个有趣的标志;我们以前可以在复制同一订阅时更改版本。
  • @LukeMerrett 在我的测试场景中,两个 SQL“服务器”(我们都知道它们不是真正的服务器,对吧?)位于同一个 DC,悉尼。通过 ping 我可以看到它们实际上都在同一个集群上(相同的 IP)。我不知道这是否是一个要求 - 我希望不是。文档没有指定,所以他们可能有“链接服务器”设置,或者可能对“作为副本”进行了一些特殊处理——我没有在 SQL Azure DB 之外看到这种语法。
  • 这对我来说非常有效。请注意,我的服务器在不同的订阅中。两台服务器上的 SQL 管理员帐户和密码相同。服务器也在同一个租户上 - 通过 Azure PowerShell 控制台检查 (Get-AzureRmSubscription -SubscriptionName ).TenantId 和 (Get-AzureRmSubscription -SubscriptionName ).TenantId - 我不必费心指定 Service_Objective,因为作为副本,我希望它们具有相同的服务目标。
  • 提示:如果您的主管理员帐户没有相同的登录名(您可能不应该这样做),您需要在源服务器上创建与目标相同的登录名您正在使用的服务器的管理员登录名。将用于该登录的用户添加到源数据库和源服务器上的主服务器。在 master 中,将其添加到 dbmanager 角色。在源数据库中,将其添加到 db_owner 角色。就是这样。
  • @ron 很棒的提示!作为记录,我更改了管理员帐户的密码,因此它们在完成任务所需的时间内是相同的,然后再次将它们放回去。但你说的很对,不要回收密码的人。
【解决方案2】:

您可以只备份(导出)到 Blob 存储,然后将其导入新订阅。

http://msdn.microsoft.com/en-us/library/f6899710-634e-425a-969d-8db1267e9471

更新: 如果您可以使用SSMS,那么这个答案是正确的。我只想补充一些细节。

  1. 您可以将源数据库导出到 Azure 门户中的存储中。
  2. 导出后,您可以找到 bacpac 文件。
  3. 打开 SSMS,并连接到目标服务器。
  4. 右击节点Database并选择Import Data-tier Application
  5. 然后您可以选择从本地磁盘或 Azure 存储导入数据库。
  6. 之后,您已将数据库从源复制到目标。

【讨论】:

  • 感谢克雷格的回答;如果CREATE DATABASE AS COPY OF 不能交叉订阅,那绝对是我们的备用计划
  • 我以这种方式进行了备份。 - 我的 DTU 达到 100% - 我重新调整 DB 两次。将来,我会在开始时重新调整它并在结束时缩小规模。(如果我会带背包) - 我的备份有些损坏 - (一些数据重复)我想是因为重新调整操作。对我来说没关系。但是,将来我会寻找另一种选择。我发现不推荐这样做:BACPACs are not intended to be used for backup and restore operations 只是让你知道
  • 这是迄今为止最慢的方法,只能作为最后的手段使用。
【解决方案3】:

我猜你已经有了解决方案,但是对于登陆这里的任何人,你可以使用 Azure PowerShell API 在源订阅中创建一个新服务器,创建一个副本并将新服务器切换到目标订阅

示例代码可在technet获得

代码是不言自明的,但是为了 SO 最佳实践,

代码的关键部分是

新建服务器:

$newserver = New-AzureSqlDatabaseServer -Location $targetServerLocation -AdministratorLogin $targetServerLoginID -AdministratorLoginPassword $targetServerLoginPassword 

创建数据库副本:

Start-AzureSqlDatabaseCopy -ServerName $sourceServerName -DatabaseName $sourceDatabaseName -PartnerServer $newserver.ServerName  -PartnerDatabase $targetdatabaseName  

转移服务器

$uri = "https://management.core.windows.net:8443/" + $sourceSubscriptionID + "/services" + "/sqlservers/servers/" + $newserver.ServerName + "?op=ChangeSubscription" 

Invoke-RestMethod -Uri $uri -CertificateThumbPrint $certThumbprint -ContentType $contenttype -Method $method -Headers $headers -Body $body 

【讨论】:

  • 跨租户是否可行?
【解决方案4】:

我已成功创建跨 Azure 订阅的数据库副本。 以下是步骤-

  1. 在目标 Azure 订阅上创建一个数据库服务器(如果您尚未创建一个),然后在该服务器上创建一个新数据库(任何名称,无关紧要),但使用与源相同的密码源 Azure 订阅上的数据库。对我来说,它不能使用不同的密码,所以我只是继续使用相同的密码,但我相信有一种方法可以让它使用不同的密码。

  2. 在目标 Azure 中新创建的数据库上运行此命令 -

创建数据库 NEWDBNAME
作为[源 Azure 服务器名称] 的副本。[源数据库]

让 Azure 处理新的数据库定价层(基本、标准等),因为您可以在创建数据库后立即从门户更改它。在我的情况下,目标数据库是使用与源数据库相同的定价层创建的。 此外,azure 中的服务器名称通常是 - NAME.database.windows.net。因此,在您上面的源名称中,只需输入 NAME。

  1. 现在,在您的目标 Azure 订阅中,您将在新的数据库服务器上拥有 2 个数据库。一个在步骤 1 中创建,另一个在步骤 2 中创建,它是实际副本。您可以继续安全地删除不需要的那个。

  2. 如果您想将其他源数据库复制到上面 1 中创建的同一目标服务器,只需再次运行相同的命令。

【讨论】:

  • 这正是我们所需要的。其他一切都太慢了!谢谢你。
  • 它也适用于 Azure 租户。而且速度非常快。对于 18 GB 的数据库,该操作用时不到五分钟。作为比较,导入/导出方法需要 5 个小时。
【解决方案5】:

您可以在目标服务器上的 SSMS 中使用

CREATE DATABASE db1 AS COPY OF sourcesrv.db1

从不同订阅的sourcesrv.database.windows.net 复制。

但是,您必须首先检查您是否也可以在 SSMS 中连接到 SOURCE 服务器,否则您将收到一个完全令人困惑的错误消息,它隐藏了实际问题。

源服务器可能是您经常连接的服务器,但不是来自您当前所在的 IP 地址。在这种情况下,您必须将 IP 添加到服务器的防火墙规则中。使用尝试从 SSMS 连接时出现的对话框可以轻松完成此操作:

选中默认单选按钮(“添加我的客户端 IP”),然后按 OK。

如果您忽略此检查,它无法对您进行身份验证,而不是如上所述告诉您正确的原因,而是告诉您无法在 SOURCE 服务器上制作副本!

--In SSMS connected to targetsrv:

CREATE DATABASE db1 AS COPY OF sourcesrv.db1

--Here it should say, "Your client IP address does not have access" to sourcesrv, like when
--you try to connect in SSMS. Instead, it says you can't copy to the SOURCE, even though you 
--told it to copy FROM the source to the TARGET:

--Msg 45137, Level 16, State 1, Line 7
--Insufficient permission to create a database copy on server 'sourcesrv'.

请注意,在撰写本文时,需要为两台服务器配置相同的管理员凭据,否则 CREATE DATABASE 命令将失败并出现同样令人困惑的错误消息。

【讨论】:

  • 您应该在原始服务器和目标服务器上拥有相同的帐户和相同的密码,以避免“在服务器 'sourcesrv' 上创建数据库副本的权限不足”错误
  • @MichaelFreidgeim 是的,这就是最后一段。我的回答说:)
  • 这适用于我的订阅,无需匹配的 SQL Server 帐户。我是源服务器和目标服务器上的服务器活动目录管理员组的成员,并使用 AD 身份验证与 MFA 进行连接。
【解决方案6】:

我知道这是一个很老的问题,但仍然想添加另一个选项。

如果您希望此任务自动化,您不想手动执行(导出-导入),您希望将数据库复制到现有服务器(而不是创建将跨订阅移动的新临时服务器) 并且出于安全考虑,您不想在源服务器和目标服务器上拥有相同的凭据,您可以使用 ARM。

有一个选项可以将数据库创建为副本 ("createMode": "Copy",),它将跨订阅创建!简单例子:

{
  "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "resources": [
    {
      "apiVersion": "2014-04-01-preview",
      "location": "australiaeast",
      "name": "{DESTINATION-SERVER-NAME}/{DESTINATION-DATABASE-NAME}",
      "properties": {
        "createMode": "Copy",
        "sourceDatabaseId": "/subscriptions/{SOURCE-SUBSCRIPTION-ID}/resourceGroups/{SOURCE-RESOURCE-GROUP-NAME}/providers/Microsoft.Sql/servers/{SOURCE-SERVER-NAME}/databases/{SOURCE-DATABASE-NAME}",
        "requestedServiceObjectiveName": "S2"
      },
      "type": "Microsoft.Sql/servers/databases"
    }
  ]
}  

需要注意两点 - 将执行此部署的服务主体需要对源具有贡献者访问权限,并且 sourceDatabaseId 是完整的资源 ID。

如果您使用“Azure 资源组部署”任务从 Azure DevOps 执行此操作 - 它将为订阅创建一个 SP。您需要授予 Contributor 访问权限。 SP 可以在项目设置 -> 服务连接中找到。

【讨论】:

  • 非常感谢! T-SQL 解决方案非常复杂,因为它们都在数据平面上。对于我的用例来说,这是一个更好的解决方案,因为它只需要控制平面上的适当权限。
【解决方案7】:

有一个更简单的解决方案,在回答此问题时可能不可用。无需 SMSS 或 PowerShell。这一切都可以在门户中完成。转到源 SQL 数据库并单击导出。这将在 Azure 存储中创建一个 .bacpac 文件。转到目标 SQL Server 并单击导入。完毕。

注意 1:如果目标 SQL Sever 位于不同的帐户/订阅中,无法访问源帐户的 Azure 存储,只需手动从源 Azure 存储下载文件并将其上传到目标可以访问的 Azure 存储实例.

注意 2:导入的数据库将具有包含导出日期的名称。您可以通过在目标数据库上运行 ALTER DATABASE [dbname] MODIFY NAME = [newdbname] 来更改名称。您甚至可以使用新的查询编辑器在门户中执行此操作。

【讨论】:

    猜你喜欢
    • 2020-09-15
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2015-05-05
    • 1970-01-01
    • 2012-06-03
    相关资源
    最近更新 更多