使用 SqlPackage 排查问题和性能问题

在某些情况下,SqlPackage 操作会花费比预期更长的时间或无法完成。 本文介绍一些常见的建议策略,用于排查这些操作的性能问题或提高性能。 建议阅读每个操作的特定文档页以了解可用的参数和属性,可以将本文作为切入点来调查 SqlPackage 操作。

整体策略

通常,可通过 .NET Core 版的 SqlPackage 来提高性能。

  1. 下载适用于所用操作系统(Windows、macOS 或 Linux)的 .NET Core 版 SqlPackage 的 zip。
  2. 按照下载页上的指示将存档解压缩。
  3. 打开命令提示符,将目录 (cd) 更改为 SqlPackage 文件夹。

请务必使用最新版本的 SqlPackage,因为性能改进和漏洞修复会定期发布。

使用 SqlPackage 替换导入/导出服务

如果你使用过导入/导出服务对你的数据库进行导入或导出,那么还可以 使用 SqlPackage 执行相同操作,支持更多对可选参数和属性的控制。

若要导入,示例命令为:

./SqlPackage /Action:Import /sf:<source-bacpac-file-path> /tsn:<full-target-server-name> /tdn:<a new or empty database> /tu:<target-server-username> /tp:<target-server-password> /df:<log-file>

若要导出,示例命令为:

./SqlPackage /Action:Export /tf:<target-bacpac-file-path> /ssn:<full-source-server-name> /sdn:<source-database-name> /su:<source-server-username> /sp:<source-server-password> /df:<log-file>

除了用户名和密码,还可以通过 Microsoft Entra 身份验证(以前的 Azure Active Directory)使用 多重身份验证 进行身份验证。 将 /ua:true/tid:"yourdomain.onmicrosoft.com" 替换为用户名和密码参数。

常见问题

超时错误

如果出现与超时相关的问题,可以使用以下属性优化 SqlPackage 和 SQL 实例之间的连接:

  • /p:CommandTimeout=:指定执行查询时命令超时(以秒为单位)。 默认:60
  • /p:DatabaseLockTimeout=:指定数据库锁定超时(以秒为单位)。 -1 可用于无限期等待,默认值:60
  • /p:LongRunningCommandTimeout=:指定长时间运行的命令超时(以秒为单位)。 默认值为 0,用于无限期等待。

客户端资源消耗

对于导出和提取命令,表数据将先传递到缓冲区的临时目录,然后再写入 bacpac/dacpac 文件。 相对于要导出数据的实际大小,该存储需求可能很大。 使用属性 /p:TempDirectoryForTableData=<path> 指定备用临时目录。

架构模型在内存中编译,因此对于大型数据库架构,运行 SqlPackage 的客户端计算机的内存需求可能很大。

服务器资源消耗低

默认情况下,SqlPackage 将最大服务器并行度设置为 8。 如果出现服务器资源消耗量较低的情况,增加 MaxParallelism 参数的值可以提高性能。

访问令牌

使用 /AccessToken:/at: 参数可为 SqlPackage 启用基于令牌的身份验证,但是将令牌传递给命令可能会很棘手。 如果在 PowerShell 中解析访问令牌对象,要么显式传递字符串值,要么将对令牌属性的引用包装在 $() 中。 例如:

$Account = Connect-AzAccount -ServicePrincipal -Tenant $Tenant -Credential $Credential
$AccessToken_Object = (Get-AzAccessToken -Account $Account -Resource "https://database.windows.net/")
$AccessToken = $AccessToken_Object.Token

SqlPackage /at:$AccessToken
# OR
SqlPackage /at:$($AccessToken_Object.Token) 

连接

如果无法连接 SqlPackage,可能是服务器未启用加密,或者配置的证书可能不是由受信任的证书颁发机构颁发(如自签名证书)。 可以将 SqlPackage 命令更改为在不加密的情况下连接或信任服务器证书。 最佳做法是确保可以与服务器建立受信任的加密连接。

  • 在不加密的情况下连接:/SourceEncryptConnection=False 或 /TargetEncryptConnection=False
  • 信任服务器证书:/SourceTrustServerCertificate=True 或 /TargetTrustServerCertificate=True

在连接到 SQL 实例时,可能会看到以下某条警告消息,表明可能需要修改命令行参数以连接到服务器:

The settings for connection encryption or server certificate trust may lead to connection failure if the server is not properly configured.
The connection string provided contains encryption settings which may lead to connection failure if the server is not properly configured.

有关 SqlPackage 中连接安全更改的详细信息,请参阅 SqlPackage 161 中的连接安全改进

导入约束的操作错误 2714

执行导入操作时,如果对象已存在,可能会收到错误 2714:

*** Error importing database:Could not import package.
Error SQL72014: Core Microsoft SqlClient Data Provider: Msg 2714, Level 16, State 5, Line 1 There is already an object named 'DF_Department_ModifiedDate_0FF0B724' in the database.
Error SQL72045: Script execution error.  The executed script:
ALTER TABLE [HumanResources].[Department]
    ADD CONSTRAINT [DF_Department_ModifiedDate_] DEFAULT ('') FOR [ModifiedDate];

以下是此错误的原因和解决方法:

  1. 验证要导入到的位置是否为空数据库。
  2. 如果数据库使用具有 DEFAULT 属性(SQL Server 为此约束分配一个随机名称)的约束,以及显式命名约束,同名约束可能会被重复创建。 建议全部使用显式命名约束(而不使用 DEFAULT),或者全部使用系统定义的名称(使用 DEFAULT)。
  3. 手动编辑 model.xml,并通过使用遇到错误的名称将约束重命名为唯一名称。 只有在 Microsoft 支持的指示下并构成 .bacpac 损坏风险时,才应执行此选项。

诊断

日志对于故障排除至关重要。 使用 /DiagnosticsFile:<filename> 参数将诊断日志捕获到文件中。

在运行 SqlPackage 之前设置环境变量 DACFX_PERF_TRACE=true,可以记录更多与性能相关的跟踪数据。 若要在 PowerShell 中设置此环境变量,请使用以下命令:

Set-Item -Path Env:DACFX_PERF_TRACE -Value true

导入操作提示

如果导入包含大型表或具有多个索引的表,使用 /p:RebuildIndexesOfflineForDataPhase=True/p:DisableIndexesForDataPhase=False 可以提高性能。 这些属性分别将索引重新生成操作修改为脱机执行或不执行。 这些属性和其他属性可用于优化 SqlPackage 导入操作。

导出操作提示

导出过程中性能下降的常见原因是未解析对象引用,这会导致 SqlPackage 多次尝试解析对象。 例如,定义了一个引用表的视图,而该表不再存在于数据库中。 如果导出日志中出现未解析的引用,请考虑更正数据库的架构以提高导出性能。

如果 OS 磁盘空间有限并在导出过程中耗尽,使用 /p:TempDirectoryForTableData 可以在备用磁盘上缓冲导出数据。 此操作所需的空间可能很大,相对于数据库的实际大小而言。 此属性和其他属性可用于优化 SqlPackage 导出操作。

在导出过程中,表数据将被压缩到 bacpac 文件中。 将 /p:CompressionOption 设置为 FastSuperFastNotCompressed 可以提高导出过程速度,同时减少对输出 bacpac 文件的压缩。

若要获取数据库架构和数据并跳过架构验证,请使用属性 /p:VerifyExtraction=False 执行导出

Azure SQL 数据库

以下提示专用于从 Azure 虚拟机 (VM) 运行针对 Azure SQL 数据库的导入或导出:

  • 使用业务关键或高级层数据库实现最佳性能。
  • 在 VM 上使用 SSD 存储,并确保有足够的空间解压缩 bacpac。
  • 从数据库所在的同一区域中的 VM 执行 SqlPackage。
  • 在 VM 中启用加速网络。

有关使用 PowerShell 脚本收集有关导入操作详细信息的详细信息,请参阅 经验与教训 #211:监视 SQLPackage 导入过程