Solución de problemas y rendimiento con SqlPackage
En algunos escenarios, las operaciones de SqlPackage tardan más de lo esperado o no se completan. En este artículo se describen algunas tácticas sugeridas con frecuencia para solucionar problemas o mejorar el rendimiento de estas operaciones. Aunque se recomienda leer la página de documentación específica de cada acción para entender los parámetros y las propiedades disponibles, este artículo sirve como punto de partida para investigar las operaciones de SqlPackage.
Estrategia general
Como guía general, se puede obtener un mejor rendimiento a través de la versión de .NET de SqlPackage en lugar de la versión de .NET Framework instalada a través del DacFramework.msi.
Si no puede instalar la herramienta dotnet de SqlPackage, que permite ejecutar comandos SqlPackage desde el símbolo del sistema en cualquier directorio:
- Descargue el archivo ZIP de SqlPackage en .NET 8 para el sistema operativo (Windows, macOS o Linux).
- Descomprima el archivo tal como se indica en la página de descarga.
- Abra un símbolo del sistema y cambie el directorio (
cd
) a la carpeta SqlPackage.
Es importante usar la última versión disponible de SqlPackage, ya que las mejoras de rendimiento y las correcciones de errores se publican periódicamente.
Sustitución de SqlPackage para el servicio Import/Export
Si ha intentado usar el servicio Import/Export para importar o exportar la base de datos, puede usar SqlPackage para realizar la misma operación con más control sobre parámetros y propiedades opcionales.
Para la importación, un comando de ejemplo es:
./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 la exportación, un comando de ejemplo es:
./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 al nombre de usuario y la contraseña, la autenticación multifactor se puede usar para autenticarse a través de la autenticación de Microsoft Entra (anteriormente Azure Active Directory) con la autenticación multifactor. Sustituya los parámetros de nombre de usuario y contraseña por /ua:true
y /tid:"yourdomain.onmicrosoft.com"
.
Problemas comunes
Errores de tiempo de espera agotado
Para problemas relacionados con los tiempos de espera, se pueden usar las siguientes propiedades para optimizar la conexión entre SqlPackage y la instancia de SQL:
/p:CommandTimeout=
: especifica el tiempo de espera del comando en segundos cuando se ejecuta una consulta. Valor predeterminado: 60/p:DatabaseLockTimeout=
: especifica el tiempo de expiración de bloqueo de la base de datos en segundos. -1 se puede usar para esperar indefinidamente; valor predeterminado: 60/p:LongRunningCommandTimeout=
: especifica el tiempo de expiración del comando de larga duración en segundos. El valor predeterminado, 0, se usa para esperar indefinidamente.
Consumo de recursos de cliente
Para los comandos de exportación y extracción, los datos de tabla se pasan a un directorio temporal para almacenarlos en el búfer antes de escribirlos en el archivo bacpac/dacpac. Este requisito de almacenamiento puede ser grande y guarda relación con el tamaño total de los datos que se van a exportar. Especifique un directorio temporal alternativo con la propiedad /p:TempDirectoryForTableData=<path>
.
El modelo de esquema se compila en memoria, por lo que para los esquemas de base de datos grandes, el requisito de memoria en el equipo cliente que ejecuta SqlPackage puede ser significativo.
Consumo bajo de recursos del servidor
De forma predeterminada, SqlPackage establece el paralelismo máximo del servidor en 8. Si observas un consumo bajo de recursos del servidor, aumentar el valor del parámetro MaxParallelism
puede mejorar el rendimiento.
Access token
El uso del parámetro /AccessToken:
o /at:
habilita la autenticación basada en tokens para SqlPackage, pero pasar el token al comando puede resultar complicado. Si va a analizar un objeto de token de acceso en PowerShell, pase explícitamente el valor de cadena o ajuste la referencia a la propiedad token en $(). Por ejemplo:
$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)
Connection
Si SqlPackage no se puede conectar, es posible que el servidor no tenga habilitado el cifrado o que el certificado configurado no se emita desde una entidad de certificación de confianza (como un certificado autofirmado). Puede cambiar el comando SqlPackage para conectarse sin cifrado o para confiar en el certificado de servidor. El procedimiento recomendado consiste en asegurarse de que se puede establecer una conexión cifrada de confianza al servidor.
- Conexión sin cifrado:
/SourceEncryptConnection:False
o/TargetEncryptConnection:False
- Certificado de servidor de confianza:
/SourceTrustServerCertificate:True
o/TargetTrustServerCertificate:True
Es posible que veas cualquiera de los siguientes mensajes de advertencia al conectarse a una instancia de SQL, lo que indica que los parámetros de la línea de comandos pueden necesitar cambios para conectarse al 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.
Puede encontrar más información sobre los cambios de seguridad de conexión en SqlPackage en Mejoras de conexión de seguridad en SqlPackage 161.
Error de acción de importación 2714 para la restricción
Al realizar una acción de importación, puede recibir el error 2714 si ya existe un objeto:
*** 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];
Estas son las causas y soluciones para resolver este error:
- Comprueba que el destino en el que vas a importar es una base de datos vacía.
- Si la base de datos tiene restricciones que usan el atributo DEFAULT (donde SQL asigna un nombre aleatorio a la restricción), y una restricción con nombre explícito, una restricción con el mismo nombre podría crearse dos veces. Debes usar todas las restricciones con nombre explícitas (sin DEFAULT) o todas las definidas por el sistema (con DEFAULT).
- Edite manualmente model.xml y cambie el nombre de la restricción por el nombre que experimenta el error en un nombre único. Esta opción solo debe realizarse si se dirige al soporte técnico de Microsoft y supone un riesgo de daños en
.bacpac
.
Excepción de desbordamiento de pila
Los scripts de T-SQL grandes con muchas instrucciones anidadas suelen ser la causa de excepciones de desbordamiento de pila intermitentes o persistentes. Cuando este es el caso, el mensaje de error incluirá el texto Stack overflow
y un seguimiento de pila 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)
Un parámetro para SqlPackage está disponible en todos los comandos, /ThreadMaxStackSize:
, que especifica el tamaño máximo de pila para el subproceso que ejecuta el proceso SqlPackage. El valor predeterminado viene determinado por la versión de .NET que ejecuta SqlPackage. Establecer un valor grande puede afectar al rendimiento general de SqlPackage, pero aumentar este valor puede resolver la excepción de desbordamiento de pila causada por instrucciones anidadas. Se recomienda refactorizar el código T-SQL para evitar excepciones de desbordamiento de pila siempre que sea posible, pero el parámetro /ThreadMaxStackSize:
se puede usar como solución alternativa.
Al usar el parámetro /ThreadMaxStackSize:
, se recomienda ajustar las operaciones repetidas al valor más bajo que resuelva la excepción de desbordamiento de pila si se observa un impacto en el rendimiento. El valor del parámetro está en megabytes (MB), los valores de ejemplo para las pruebas como solución alternativa incluyen 10 y 100.
Diagnóstico
Los registros son esenciales para solucionar problemas. Capture los registros de diagnóstico en un archivo con el parámetro /DiagnosticsFile:<filename>
.
Se pueden registrar datos de seguimiento adicionales relacionados con el rendimiento estableciendo la variable de entorno DACFX_PERF_TRACE=true
antes de ejecutar SqlPackage. Para establecer esta variable de entorno en PowerShell, use el siguiente comando:
Set-Item -Path Env:DACFX_PERF_TRACE -Value true
Sugerencias de acción de importación
Para las importaciones que contienen tablas de gran tamaño o tablas con muchos índices, el uso de /p:RebuildIndexesOfflineForDataPhase=True
o /p:DisableIndexesForDataPhase=False
puede mejorar el rendimiento. Estas propiedades modifican la operación de recompilación de índices para que se produzca sin conexión o no se produzca, respectivamente. Esas y otras propiedades están disponibles para optimizar la operación SqlPackage Import.
Sugerencias de acción de exportación
Una causa común de degradación del rendimiento durante la exportación son las referencias a objetos sin resolver, lo que provoca que SqlPackage intente resolver el objeto varias veces. Por ejemplo, se define una vista que hace referencia a una tabla, y la tabla ya no existe en la base de datos. Si las referencias sin resolver aparecen en el registro de exportación, considere la posibilidad de corregir el esquema de la base de datos para mejorar el rendimiento de la exportación.
En escenarios en los que el espacio en disco del sistema operativo es limitado y se agota durante la exportación, el uso de /p:TempDirectoryForTableData
permite almacenar en búfer los datos para la exportación en un disco alternativo. El espacio necesario para esta acción puede ser grande y depende del tamaño completo de la base de datos. Esa y otras propiedades están disponibles para optimizar la operación SqlPackage Export.
Durante un proceso de exportación, los datos de la tabla se comprimen en el archivo bacpac. El uso de /p:CompressionOption
establecido en Fast
, SuperFast
o NotCompressed
puede mejorar la velocidad del proceso de exportación al comprimir menos el archivo bacpac de salida.
Para obtener el esquema y los datos de la base de datos mientras se omite la validación del esquema, realice una exportación con la propiedad /p:VerifyExtraction=False
. Se puede producir una exportación no válida que no se pueda importar.
Azure SQL Database
Las siguientes sugerencias son específicas para ejecutar la importación o exportación en Azure SQL Database desde una máquina virtual (VM) de Azure:
- Use Crítico para la empresa o base de datos de nivel Premium para obtener el mejor rendimiento.
- Use el almacenamiento SSD en la máquina virtual.
- Asegúrese de que hay suficiente espacio para descomprimir el bacpac.
- Ejecute SqlPackage desde una máquina virtual en la misma región que la base de datos.
- Habilite redes aceleradas en la máquina virtual.
Para obtener más información sobre el uso de un script de PowerShell para recopilar más información sobre una operación de importación, vea Lección aprendida #211: Supervisión del proceso de importación de SQLPackage.
Más recursos
El blog de soporte técnico de Azure Database contiene muchos artículos sobre la solución de problemas y el ajuste del rendimiento de Azure SQL Database, incluidos varios artículos sobre SqlPackage.
Algunos de los artículos más relevantes incluyen:
- Migración de una base de datos de Azure SQL a una instancia de SQL MI mediante SqlPackage/ADF
- Lección aprendida n.º 446: Simplificación de la depuración de registros de SQLPackage con PowerShell
- Cómo usar Sqlpackage con la identidad administrada
- Lección aprendida n.º 298: Enorme duración de la exportación de bases de datos mediante sqlpackage
- Lección aprendida n.º 281: Se produce un error en la exportación debido a una excepción de memoria insuficiente del sistema
- Lección aprendida n.º 281: Solución de problemas de restricción CHECK al importar un bacpac debido a la lógica de negocios
- Lección aprendida n.º 272: Mensaje de error de expiración de tiempo de espera de ejecución al importar un archivo Bacpac
- Lección aprendida n.º 213: no se puede establecer la propiedad AccessToken si se ha establecido la seguridad integrada
- Lección aprendida 211: Supervisión del proceso de importación de SQLPackage
- Lección aprendida n.º 51: Instancia administrada: la importación a través de Sqlpackage.exe no permite el crecimiento automático
- Lección aprendida n.º 32: Cómo exportar varias bases de datos de SQL Server a Bacpac
- Paso a paso: Uso de SQLPackage con token de acceso
- Conflicto de intercalación al mover una base de datos de Azure SQL a SQL Server local o máquina virtual de Azure mediante SQLPackage.