Solucionar problemas e desempenho com SqlPackage
Em alguns cenários, as operações SqlPackage levam mais tempo do que o esperado ou não são concluídas. Este artigo descreve algumas táticas frequentemente sugeridas para solucionar problemas ou melhorar o desempenho dessas operações. Embora a leitura da página de documentação específica para cada ação para entender os parâmetros e propriedades disponíveis seja recomendada, este artigo serve como um ponto de partida na investigação de operações SqlPackage.
Estratégia global
Como diretriz geral, um melhor desempenho pode ser obtido por meio da versão .NET do SqlPackage em vez da versão do .NET Framework instalada através do DacFramework.msi.
Se não conseguires instalar a ferramenta do SqlPackage do .NET, que permite executar comandos do SqlPackage a partir da linha de comandos em qualquer diretório:
- Download o zip para SqlPackage no .NET 8 para seu sistema operacional (Windows, macOS ou Linux).
- Descompacte o arquivo conforme indicado na página de download.
- Abra um prompt de comando e altere o diretório (
cd
) para a pasta SqlPackage.
É importante usar a versão mais recente disponível do SqlPackage, pois melhorias de desempenho e correções de bugs são lançadas regularmente.
Substitua SqlPackage pelo serviço de importação/exportação
Se você tentou usar o Serviço de Importação/Exportação para importar ou exportar seu banco de dados, poderá usar SqlPackage para executar a mesma operação com mais controle sobre parâmetros e propriedades opcionais.
Para Importar, um comando de exemplo é:
./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>
Para Exportar, um comando de exemplo é:
./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>
Alternativa ao nome de utilizador e senha, a autenticação multifator pode ser usada para autenticar através da autenticação Microsoft Entra (anteriormente Azure Active Directory) com autenticação multifator. Substitua os parâmetros de nome de usuário e senha por /ua:true
e /tid:"yourdomain.onmicrosoft.com"
.
Diagnóstico
O diagnóstico de erros e comportamento inesperado em SqlPackage é suportado por logs de diagnóstico e um pacote de diagnóstico. Os logs de diagnóstico são essenciais para a solução de problemas e são capturados em um arquivo com o parâmetro /DiagnosticsFile:<filename>
.
O nível de detalhe na saída de diagnóstico é controlado através do parâmetro /DiagnosticsLevel
. Os valores de Information
e Verbose
são úteis para obter mais detalhes.
Os dados de rastreamento relacionados ao desempenho podem ser registrados definindo a variável de ambiente DACFX_PERF_TRACE=true
antes de executar SqlPackage. Os dados de rastreamento aumentam a saída do log; portanto, incluir apenas ao diagnosticar desafios de desempenho. Para definir essa variável de ambiente no PowerShell, use o seguinte comando:
Set-Item -Path Env:DACFX_PERF_TRACE -Value true
No SqlPackage 162.5 e posterior, um pacote de diagnóstico pode ser gerado para ajudar na solução de problemas. O pacote de diagnóstico contém a versão SqlPackage, o comando executado, informações sobre os modelos de banco de dados de origem e destino e a saída do comando. Para gerar um pacote de diagnóstico, use o parâmetro /DiagnosticsPackageFile:<filename>
.
Problemas comuns
Erros de tempo limite
Para problemas relacionados a timeouts, as seguintes propriedades podem ser usadas para configurar a conexão do SqlPackage com a instância SQL.
-
/p:CommandTimeout=
: Especifica o tempo limite do comando em segundos quando uma consulta é executada. Padrão: 60 -
/p:DatabaseLockTimeout=
: Especifica o tempo limite de bloqueio do banco de dados em segundos. -1 pode ser usado para esperar indefinidamente, padrão: 60 -
/p:LongRunningCommandTimeout=
: Especifica o tempo limite do comando de longa execução em segundos. O valor padrão, 0, é usado para aguardar indefinidamente.
Consumo de recursos do cliente
Para os comandos export e extract, os dados da tabela são passados para um diretório temporário para buffer antes de serem gravados no arquivo bacpac/dacpac. Esse requisito de armazenamento pode ser grande e é relativo ao tamanho total dos dados a serem exportados. Especifique um diretório temporário alternativo com a propriedade /p:TempDirectoryForTableData=<path>
.
O modelo de esquema é compilado na memória, portanto, para esquemas de banco de dados grandes, o requisito de memória na máquina cliente que executa o SqlPackage pode ser significativo.
Baixo consumo de recursos do servidor
Por padrão, SqlPackage define o paralelismo máximo do servidor como 8. Se você observar um baixo consumo de recursos do servidor, aumentar o valor do parâmetro MaxParallelism
pode melhorar o desempenho.
Token de acesso
Usar o parâmetro /AccessToken:
ou /at:
permite a autenticação baseada em token para SqlPackage, no entanto, passar o token para o comando pode ser complicado. Se você estiver analisando um objeto de token de acesso no PowerShell, passe explicitamente o valor da cadeia de caracteres ou envolva a referência à propriedade do token em $(). Por exemplo:
$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)
Ligação
Se o SqlPackage não estiver conseguindo se conectar, o servidor pode não ter a criptografia habilitada ou o certificado configurado pode não ser emitido por uma autoridade de certificação confiável (como um certificado autoassinado). Você pode alterar o comando SqlPackage para se conectar sem criptografia ou para confiar no certificado do servidor. A de prática recomendada é garantir que uma conexão criptografada confiável com o servidor possa ser estabelecida.
- Ligar sem encriptação:
/SourceEncryptConnection:False
ou/TargetEncryptConnection:False
- Certificado do servidor confiável:
/SourceTrustServerCertificate:True
ou/TargetTrustServerCertificate:True
Você pode ver qualquer uma das seguintes mensagens de aviso ao se conectar a uma instância SQL, indicando que os parâmetros de linha de comando podem exigir alterações para se conectar ao servidor:
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.
Mais informações sobre as alterações de segurança de conexão no SqlPackage estão disponíveis em Melhorias de segurança de conexão no SqlPackage 161.
Erro de ação de importação 2714 para restrição
Ao executar uma ação de importação, você pode receber o erro 2714 se um objeto já existir:
*** 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];
Aqui estão as causas e soluções para contornar esse erro:
- Verifique se o destino para o qual você está importando é um banco de dados vazio.
- Se seu banco de dados tiver restrições que estão usando o atributo DEFAULT (onde o SQL Server atribui um nome aleatório à restrição) e uma restrição explicitamente nomeada, uma restrição com o mesmo nome pode ser criada duas vezes. Você deve usar todas as restrições explicitamente nomeadas (não usando DEFAULT) ou todos os nomes definidos pelo sistema (usando DEFAULT).
- Edite manualmente o model.xml e renomeie a restrição com o nome que está apresentando o erro para um nome exclusivo. Esta opção deve ser realizada somente se dirigido pelo suporte da Microsoft e representa um risco de corrupção
.bacpac
.
Exceção de estouro de pilha
Scripts T-SQL grandes com muitas instruções aninhadas geralmente são a causa de exceções de estouro de pilha intermitentes ou persistentes. Quando for esse o caso, a mensagem de erro incluirá o texto Stack overflow
e um rastreamento de pilha de:
Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor.Visit(Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression)
Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor.ExplicitVisit(Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.Accept(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.AcceptChildren(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.Accept(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.AcceptChildren(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Um parâmetro para SqlPackage está disponível em todos os comandos, /ThreadMaxStackSize:
, que especifica o tamanho máximo da pilha para o thread que executa o processo SqlPackage. O valor padrão é determinado pela versão .NET que executa SqlPackage. Definir um valor grande pode afetar o desempenho geral do SqlPackage; contudo, aumentar este valor pode resolver a exceção de estouro de pilha causada por instruções aninhadas. A refatoração do código T-SQL é recomendada para evitar exceções de estouro de pilha sempre que possível, mas o parâmetro /ThreadMaxStackSize:
pode ser usado como uma solução alternativa.
Ao usar o parâmetro /ThreadMaxStackSize:
, é aconselhável ajustar as operações repetidas para o menor valor possível que resolve a exceção de estouro de pilha, caso se observe impacto no desempenho. O valor do parâmetro está em megabytes (MB), os valores de exemplo para teste como uma solução alternativa incluem 10 e 100.
Importar dicas de ação
Para importações que contêm tabelas grandes ou tabelas com muitos índices, o uso de /p:RebuildIndexesOfflineForDataPhase=True
ou /p:DisableIndexesForDataPhase=False
pode melhorar o desempenho. Essas propriedades modificam a operação de reconstrução de índice para ocorrer offline ou não ocorrer, respectivamente. Essas e outras propriedades estão disponíveis para ajustar a operação SqlPackage Import.
Dicas para ações de exportação
Uma causa comum de degradação do desempenho durante a exportação são referências de objeto não resolvidas, o que faz com que SqlPackage tente resolver o objeto várias vezes. Por exemplo, é definido um modo de exibição que faz referência a uma tabela e a tabela não existe mais no banco de dados. Se referências não resolvidas aparecerem no log de exportação, considere corrigir o esquema do banco de dados para melhorar o desempenho da exportação.
Em cenários em que o espaço em disco do sistema operacional é limitado e se esgota durante a exportação, o uso de /p:TempDirectoryForTableData
permite que os dados para exportação sejam armazenados em buffer em um disco alternativo. O espaço necessário para essa ação pode ser grande e é relativo ao tamanho total do banco de dados. Essa e outras propriedades estão disponíveis para ajustar a operação SqlPackage Export.
Durante um processo de exportação, os dados da tabela são compactados no arquivo bacpac. O uso de /p:CompressionOption
definido como Fast
, SuperFast
ou NotCompressed
pode melhorar a velocidade do processo de exportação enquanto compacta menos o arquivo bacpac de saída.
Para obter a estrutura e os dados do banco de dados, enquanto se ignora a validação da estrutura, execute um Export com a propriedade /p:VerifyExtraction=False
. Pode ser produzida uma exportação inválida que não pode ser importada.
Banco de Dados SQL do Azure
As dicas a seguir são específicas para executar a importação ou exportação no Banco de Dados SQL do Azure a partir de uma máquina virtual (VM) do Azure:
- Use o banco de dados de nível Business Critical ou Premium para obter o melhor desempenho.
- Use o armazenamento SSD na VM.
- Certifique-se de que há espaço suficiente para descompactar o bacpac.
- Execute SqlPackage a partir de uma VM na mesma região do banco de dados.
- Habilite a rede acelerada na VM.
Para obter mais informações sobre como utilizar um script do PowerShell para coletar mais informações sobre uma operação de importação, consulte Lição aprendida #211: Monitorando o processo de importação SQLPackage.
Mais recursos
O Blog de Suporte do Banco de Dados do Azure contém muitos artigos sobre solução de problemas e ajuste de desempenho para o Banco de Dados SQL do Azure, incluindo vários artigos sobre SqlPackage.
Alguns dos artigos mais relevantes incluem:
- Migrando um Banco de Dados SQL do Azure para um SQL MI utilizando SqlPackage/ADF
- Lição aprendida #446: Simplificando a depuração de log SQLPackage com o PowerShell
- Como usar o Sqlpackage com o Managed Identity
- Lição aprendida #298: Enorme duração da exportação de banco de dados usando sqlpackage
- Lição aprendida #281: A exportação falha devido à exceção de falta de memória do sistema
- Lição aprendida #281: Solucionando problemas de restrição CHECK ao importar um bacpac devido à lógica de negócios
- Lição aprendida #272: Tempo limite de execução expirado mensagem de erro importando um arquivo Bacpac
- Lição Aprendida #213: Não é possível definir a propriedade AccessToken se a Segurança Integrada tiver sido definida
- Lição Aprendida #211: Monitorizar o Processo de Importação SQLPackage
- Lição aprendida #51: Instância gerenciada - A importação via Sqlpackage.exe não permite o crescimento automático
- Lição aprendida #32: Como exportar vários bancos de dados do SQL Server para o Bacpac
- passo a passo: Como usar o SQLPackage com o Access Token
- Conflito de agrupamento ao mover o Banco de Dados SQL do Azure para o SQL Server local ou a VM do Azure usando SQLPackage.