Etiquetado: MSSql

Migración de SQL Server a Windows Azure SQL Database

Ultralight MigrationEsta semana estábamos haciendo una prueba de concepto para una empresa colaboradora y necesitábamos mover una base de datos de unos 2GB a SQL Azure para realizar las pruebas con datos reales. Gracias a Azure y SQL Azure, en unas pocas horas hemos tenido la BBDD lista y funcionando sin problema con la aplicación cliente en una máquina virtual en Azure utilizando vitualización de aplicaciones, pero eso es otra historia que os contará Nacho algún día.

Nuestro trabajo empezó con una entrevista al dba y al desarrollador para que nos contaran cómo utilizaban la BBDD y averiguar si se usaba alguna funcionalidad incompatible con SQL Azure. Hemos encontrado bastantes casos en los que se hacen cross-queries entre diferentes BBDD del mismo servidor e incluso de servidores diferentes, este es uno de los primeros criterios KO que procuramos descartar. Otras funcionalidades incompatibles son los procedimientos almacenados en .NET y algunos campos especiales como filestream.

Suele ocurrir que las BBDD han pasado por muchas manos y mantienen algunos datos y metadatos obsoletos que nadie conoce, así que aunque el cliente nos jure que no está utilizando ninguna de esas funcionalidades, recordad la sabiduría del doctor House: “Everybody lies”.

El asistente de SSMS

En versiones anteriores de las herramientas necesitábamos crear un paquete datpac con las SQL Server Data Tools para después desplegarlo a SQL Azure. Si no queríamos fallar estrepitosamente, era conveniente utilizar alguna herramienta de comprobación de compatibilidad con SQL Azure.
Por suerte, la versión 2012 del Microsoft SQL Server Management Studio (SSMS) viene con un asistente que nos facilitará la migración. Este comprueba casi todas las incompatibilidades antes de empezar el despliegue a Azure y nos ahorrará muchos disgustos.

El asistente de SSMS nos pedirá los datos de conexión al servidor de SQL Azure, el tamaño de la BBDD destino y dónde va a guardar el fichero temporal .bacpac, que contendrá todos los datos necesarios para realizar la migración de la BBDD.

Una vez introducidos los campos que nos pide, el procedimiento comprobará nuestro esquema y nos proporcionará un listado de fallos, para que los vayamos arreglando antes de enviar la carga de datos a Azure:

Vistas

El primer fallo que encontramos nos lo dio en las vistas. Es posible que contengan alguna cross-query y el cliente ya no se acuerde, o que provenga de alguna migración antigua y tenga como prefijo el nombre de la BBDD, por ejemplo:

SELECT CAMPO1, CAMPO2 FROM [BBDD].[USUARIO].[TABLA]

Si se da este caso el procedimiento de migración fallará y tendremos que volver a empezar. Por suerte el wizard de migración nos proporcionará la lista de errores de comprobación y podremos ver qué vistas están fallando para editarlas antes de realizar la migración completa.

Propiedades Extendidas

Las propiedades extendidas son algo que suele pasar desapercibido, probablemente porque sirven para documentar la BBDD. Desde el diseñador podemos poner comentarios en los objetos de la BBDD, estos se guardarán como propiedades extendidas en el esquema de BBDD. Si desde el SSMS pedimos que nos genere el script de una tabla o una vista, muchas veces encontraremos además de la información de esquema, unas llamadas a un procedimiento almacenado llamado sp_addextendedproperty. En algunos casos serán nuestros comentarios, otras veces será información que guarda el propio SSMS cuando diseñamos una tabla o vista de manera visual.

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'una descripción' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Table_1', @level2type=N'COLUMN',@level2name=N'ABC'

SQL Azure no permite estas propiedades, así que hay que eliminarlas antes de realizar la migración. En nuestro caso, encontramos muchas propiedades tanto a nivel de campo como a nivel de vista. Borrarlas una por una sería una tarea demasiado larga. Me irrita especialmente tener que repetir más de dos veces cualquier tarea mecánica; por suerte alguien creó un script para encontrar y eliminar todas esas propiedades extendidas. Nosotros lo adaptamos a nuestras necesidades, pues detectamos que sólo teníamos propiedades extendidas para campos y vistas, así que ignoramos las tablas:

select 'EXEC sp_dropextendedproperty
@name = '''+extended_properties.name+'''
,@level0type = ''schema''
,@level0name = ' + object_schema_name(extended_properties.major_id) + '
,@level1type = ''table''
,@level1name = ' + object_name(extended_properties.major_id) + '
,@level2type =  ''column''
,@level2name = ' + columns.name
from sys.extended_properties
join sys.columns
on columns.object_id = extended_properties.major_id
and columns.column_id = extended_properties.minor_id
where extended_properties.class_desc = 'OBJECT_OR_COLUMN'
and extended_properties.minor_id > 0
UNION
select 'EXEC sp_dropextendedproperty
@name = '''+extended_properties.name+'''
,@level0type = ''schema''
,@level0name = ' + object_schema_name(extended_properties.major_id) + '
,@level1type = ''view''
,@level1name = ' + object_name(extended_properties.major_id)
from sys.extended_properties
join sys.views
on views.object_id = extended_properties.major_id
where extended_properties.class_desc = 'OBJECT_OR_COLUMN'

Este código nos devolverá tantas filas como objetos tengamos con propiedades extendidas en campos y vistas. Copiamos el resultado de la consulta y la pegamos en una ventana nueva de consulta. Al ejecutar todos esos comandos que acabamos de crear con la consulta, borraremos todas las propiedades extendidas que nos molestaban.

Tablas, índices y claves

El SQL Azure es bastante tiquismiquis en este sentido y exige que todas las tablas tengan al menos un índice y que los índices sean agrupados (clustered). Siempre te encuentras con algún despistado que creó una tabla sin una PK. A veces ocurre en el caso de tablas de dominio pequeñas, con valores que casi no se usan y no tienen un mantenimiento; puede que estén años así sin que nadie se de cuenta.

Cross-Triggers

Nos aseguramos de que no hacían cross-queries, pero no les preguntamos si hacían cross-triggers y estos, por supuesto, son también incompatibles con SQL Azure. Encontrarlos puede ser un poco más complicado, porque tendríamos que ir uno por uno a ver qué trigger está utilizando esos datos. Por suerte, el sistema de migración crea un archivo llamado BACPAC que contiene un backup completo de la base de datos, con sus procedimientos, triggers, etc, donde podremos encontrarlos.

Si no le hemos dicho lo contrario al SSMS, podremos encontrar el archivo BACPAC dentro de %temp% y aunque la extensión es desconocida (.bacpac) podemos cambiarla a .zip y así ver el contenido del archivo. Encontraremos en él un archivo model.xml con todos los scripts de creación de la BBDD, así que buscando la palabra trigger podremos ir encontrando todos los que hay e investigar si son válidos para Azure o no.

Usuarios

La primera vez que conseguimos desplegar el esquema en SQL Azure nos encontramos usuarios de BBDD pertenecientes a un dominio de Windows, como esto no tenía sentido en nuestro escenario y eran restos de una implementación antigua, decidimos quitarlo directamente, ya investigaremos más adelante si nos encontramos con esta necesidad.

Timeout!

Una vez con la BBDD limpia pensamos que ya lo teníamos todo y pusimos en marcha el procedimiento de migración de nuevo. Era sólo cuestión de esperar que subiera todo el contenido y empezar a trabajar. El problema con una BBDD con muchos datos es que el procedimiento del SSMS no está demasiado refinado todavía y lo más probable es que tengamos algún timeout cuando se están subiendo tablas con grandes cantidades de datos.

Si recordáis el asistente del principio del artículo, el paquete BACPAC se genera en la carpeta %temp% de nuestra máquina.

Antes de perder demasiado tiempo en buscar valores de la configuración para aumentar el tiempo de expiración, debemos saber que podemos subir el paquete BACPAC al Azure Storage y acabar el procedimiento de migración desde el portal de Azure.

Una herramienta gratuita que he encontrado para subir paquetes al storage es: http://azurestorageexplorer.codeplex.com/

Una vez subido el paquete a un blob de nuestra cuenta de Azure Storage sólo nos queda poner en marcha la importación. Desde el nuevo portal todavía no está la opción que explican aquí, así que tuvimos que volver al portal antiguo en el que encontramos todas las funcionalidades. Una vez en el portal es muy sencillo, vamos al apartado de BBDD y en el ribbon seleccionamos “import”:

Para la importación nos pedirá los mismos datos que nos pedía el asistente, además de la url y clave de acceso del Blob donde hemos guardado el archivo BACPAC.

Con todos estos datos se creará una tarea de importación, que podremos ir vigilando por si nos falla en algún momento.

Entre fallo y fallo

Si el proceso nos falla por algún motivo y tenemos que volver a empezar, es muy probable que tengamos que borrar la base de datos del servidor de SQL Azure que hemos creado. Como es un proceso en batch, es posible que la BBDD esté bloqueada mientras se acaba de generar todo el log del procedimiento fallido y no nos dejará borrar la base de datos hasta pasado un cierto tiempo.
Para que no se nos alargue demasiado el tiempo de espera, si estamos realizando la migración a un servidor sin otras bases de datos, podemos eliminar el servidor completo y volver a crearlo.

Otras herramientas y enlaces útiles

Anuncios

Nuevas charlas de Baleares on .Net

Podéis leer en el blog de Javier Jofre que hay dos nuevas charlas sobre MS SQL Server 2008 preparadas por la gente de Innova. El equivalente al Heroes Community Launch para SQL Server 2008. Serán:
Viernes 24 Octubre:
– Carlos A. García: Tipos de datos nuevos en SQL Server 2008.- Pedro Bauzá: Sql Server 2008 versus SQL Server 2005.
Jueves 20 Noviembre:
– Javier Jofre: Reporting Services con SQL Server 2008.