Estrategia de Copia de Datos

Replicar Estructura de Base de Datos Origen en el Destino

La configuración por defecto que emplea Insert Bulk Bestia se basa en que la estructura de las bases de datos de origen y destino es la misma. Así, para el origen generará cláusulas SELECT para cada una de las tablas que contendrán todos los campos, siendo el orden el definido en "sys.columns". Para el destino, también generará cláusulas SELECT de la misma forma. El emparejamiento de campos que se realiza en la instrucción SqlBulkCopy será siguiendo el orden en que aparecen los campos en ambas cláusulas SELECT, no por el nombre de los campos.

Si en la base de datos de destino se han realizado modificaciones en la estructura debido a los desarrollos continuos, Insert Bulk Bestia no tiene el conocimiento suficiente como para averiguar la correspondencia entre la estructura origen y la de destino. Así, deberá ser el operador de la aplicación el que deba indicar las relaciones modificando adecuadamente las SELECT anteriormente descritas.

El comportamiento por defecto de Insert Bulk Bestia es el apropiado cuando la base de datos destino es una réplica de la base de datos origen. ¿Cuándo no sucederá esto? Normalmente sucederá cuando ya no se pueda garantizar que lo que existe en "producción" es igual a lo que existe en los entornos de "test" y "desarrollo". En esos casos, lo conveniente es eliminar las bases de datos de "test" y "desarrollo" y comenzar desde cero a crear las bases de datos.

Así, el primer paso será replicar la estructura de la base de datos de producción en el resto de los entornos. Para ello, se puede hacer uso de los recursos que SQL Server Management Studio pone a disposición del operador de la aplicación. En las figuras siguientes, se describe el proceso a seguir para obtener una réplica de la estructura de la base de datos origen en los entornos de destino.

Nota: Aunque en las imágenes se muestre el interfaz de SSMS en inglés, en determinadas ocasiones también se mostrará la imagen correspondiente en castellano con el fin de facilitar la selección de opciones a los usuarios que muy inteligentemente opten por el uso y fomento de este idioma.

En primer lugar, se muestra cómo arrancar el asistente que ayudará a obtener un script con la estructura de la base de datos origen:

Generación del Script con la Estructura de la Base de Datos - 1

Generación del Script con la Estructura de la Base de Datos - 1

Tras seleccionar la generación del script para la base de datos completa, se recomienda realizar la selección de las opciones avanzadas (ficha General) mostradas en la siguiente figura. Se describen algunas de ellas por su especial importancia.

Generación del Script con la Estructura de la Base de Datos - 2

Generación del Script con la Estructura de la Base de Datos - 2

Generación del Script con la Estructura de la Base de Datos - 2 - ES

  • Incluir encabezados descriptivos: Es conveniente no seleccionar esta opción, ya que facilitará la comparación del script generado con otros generados anteriormente para comprobar las modificaciones realizadas.
  • Incluir intercalación: En muchas ocasiones, las instalaciones de las instancias de SQL Server no suelen ser iguales en todos los entornos, por lo que es conveniente asegurar que en todos los entornos la definición de las tablas sea la misma.
  • Incluir nombres de restricción del sistema: Aunque todos los elementos creados por Insert Bulk Bestia tienen nombre, es costumbre por parte de los programadores dejar al "libre albedrío" de SQL Server asignar nombres de forma automática a determinados objetos, como las restricciones. Si la lógica de negocio requiere la inhabilitación de alguna de ellas y posteriormente su rehabilitación, es conveniente que el nombre dado en el resto de entornos sea el mismo que el dado en producción.
  • Incluir propiedades extendidas en el script: Insert Bulk Bestia hace uso de estas propiedades para indicar la versión de los objetos creados y utilizados por la aplicación. Si no se incluyen dichas propiedades, los objetos serán eliminados y creados otra vez, con lo que la información guardada en ellos se perderá.
  • Tipos de datos que se deben incluir en el script: Dado que sólo se desea recrear la estructura de la base de datos, se debe escoger la opción "Sólo esquema".

En la ficha de "Opciones de tabla o vista", la selección recomendada es la mostrada a continuación:

Generación del Script con la Estructura de la Base de Datos - 3

Generación del Script con la Estructura de la Base de Datos - 3

Generación del Script con la Estructura de la Base de Datos - 3 - ES

  • Incluir seguimiento de cambios: Dado que Insert Bulk Bestia va a desmontar parte de la estructura de la base de datos y volverla a montar, es recomendable la desactivación de esta opción si el usuario utilizado para este proceso no tiene los permisos adecuados. Más adelante se detallarán los permisos que necesita dicho usuario, siempre y cuando no se active el seguimiento de cambios.

Generación del Script con la Estructura de la Base de Datos - 4

Generación del Script con la Estructura de la Base de Datos - 4

Una vez generado el script, éste se debe adaptar al entorno al cual va dirigido. En la figura anterior se ha querido resaltar que normalmente la estructura de discos de los diferentes entornos no suele ser igual, por lo que las rutas para la creación de ficheros deben adaptarse al entorno.

Por último, indicar que si se desea otro nombre para la base de datos, simplemente hay que buscar y reemplazar en el script dicho nombre por el deseado.

Estrategia de Copia de Datos

La idea es bastante sencilla, lo cual siempre lleva a grandes complicaciones. A grandes rasgos los pasos a seguir son:

  1. Reproducir en los entornos de destino la estructura de la base de datos que se desea "copiar".
  2. Instalar y Licenciar Insert Bulk Bestia en una máquina intermedia de forma que no cargue innecesariamente los servidores de origen y destino.
  3. Realizar una primera copia desde el origen al primer destino. Esta copia puede configurarse para que no sobrecargue el servidor de origen, en el caso de que éste sea el servidor de producción y se encuentra ONLINE.
  4. Realizar el resto de copias desde el primer destino al resto de destinos, ahora ya aprovechando el máximo de recursos disponibles.

Estrategia de Copia de Datos - 1

Estrategia de Copia de Datos - 1

Proceso de Copia de Datos

Como ya se ha anunciado, las ideas sencillas,..., conllevan un gran trabajo y esfuerzo. Así, con el fin de que el proceso de copia de datos sea lo más automático posible, la configuración y realización de la primera de las copias es algo más complicado que el resto de copias, ya que el resto de copias van a estar basadas en esta primera configuración.

Para ello, Insert Bulk Bestia está diseñado para crear determinados objetos en la base de datos de origen que tienen su réplica en la base de datos destino. Los objetos que Insert Bulk Bestia crea en el origen son:

  • Objetos auxiliares: Tabla ibb.Log_Errores junto con los procedimientos almacenados para facilitar su uso. También se incluyen las librerías ASSEMBLY SQLServerSafeFunctions y ASSEMBLY SQLServerAutonomousCalls
    • La utilidad de estos objetos es que quede registrada la actividad realizada por Insert Bulk Bestia en el origen, e informar de cualquier excepción que pudiese ocurrir durante la carga.
  • Procedimientos almacenados para las Acciones Personalizadas: ibb.Cargar_Tablas_Acciones_Programables_Origen, ibb.Cargar_Tablas_Acciones_Programables_Destino_Iniciales y ibb.Cargar_Tablas_Acciones_Programables_Destino_Finales.
    • Son procedimientos almacenados vacíos de acciones. Están pensados para que en ellos, el operador pueda programar acciones que se ejecutarán en determinados momentos de la carga.
    • Se crean en el origen para que cuando se replique la estructura de la base de datos en el destino, las acciones programadas por el usuario vayan incluidas. De esta forma, se evita que el operador tenga que reprogramarlas una y otra vez.
  • Procedimientos almacenados para la actualización de la estructura de las bases de datos origen y destino: ibb.Cargar_Tablas_Actualiza e ibb.Cargar_Tablas_Actualiza_Secuencias. Estos procedimientos son los encargados de actualizar en las Tablas de Carga la estructura de la base de datos origen y destino.
    • Aunque el operador, puede modificarlos para adaptarlos a sus necesidades concretas, se recomienda no hacerlo, y realizar las acciones deseadas en los procedimientos almacenados mencionados anteriormente.

Por último, existen dos objetos, que también se crean en el origen, y cuya estrategia de funcionamiento es conveniente detallar para que el operador comprenda qué posibilidades tiene a la hora de programar las acciones personalizadas para que la carga de datos se ajuste a sus necesidades:

  • Tablas de Carga: ibb.Cargar_Tablas, ibb.Cargar_Tablas_Secuencias y tablas auxiliares. En la primera de ellas se almacena la estructura de las bases de datos origen y destino necesaria para la carga de datos. En la segunda, se almacenan las secuencias existentes en el origen y destino.
    • En ibb.Cargar_Tablas, se guardan las cláusulas SELECT y WHERE que indican los datos a copiar del origen y dónde se deben copiar en el destino. Además, contiene la clasificación de las tablas y la segmentación de las mismas.
    • En ibb.Cargar_Tablas_Secuencias, se indican las secuencias existentes y cómo se deben reiniciar para que una vez copiados los datos, dichas secuencias funcionen correctamente.

Durante la carga de datos, se leerá la estructura de la base de datos origen, se guardará en los objetos de la dicha base de datos, se trasladará dicha información a la base de datos de destino y allí se actualizará con la información de la estructura de la base de datos destino.

Estructura de Origen y Destino - 1

Estructura de Origen y Destino - 1

  • 1- Lectura de la Estructura del Origen

    Lectura de la estructura de la Base de Datos Origen. Estos pasos se ejecutan si en la parametrización del origen se encuentra marcada la opción Actualizar Lista de Tablas, y por supuesto, la opción Crear Objetos en Origen:

    • Inserta en ibb.Cargar_Tablas todo aquello que no tiene almacenado. Rellena los campos SELECT tanto del origen como del destino. Por defecto, el campo 'ClasificacionTabla' se rellena con 0.
    • Actualiza en ibb.Cargar_Tablas los campos SELECT del origen con las modificaciones que haya sufrido la base de datos origen. Este paso se corresponde con la opción de configuración del origen Actualizar Cláusula SELECT.
    • Elimina de ibb.Cargar_Tablas aquellos registros correspondientes a tablas que han desaparecido en el origen.
    • Actualiza el número de filas de cada tabla, el espacio que ocupan los datos de cada tabla y el espacio que ocupan los índices de cada tabla. Actualiza en campo 'ClasificacionTabla' a 255 para aquellas tablas con "durability = 1".
  • 2- Copiar de la Estructura del Origen en el Destino

    Siempre se trunca la tabla ibb.Cargar_Tablas_Copia_Origen del destino.

    Si en la parametrización del origen se encuentra marcada la opción Copiar Lista Tablas al Destino:

  • 3- Actualización del Destino con la Estructura del Origen

    Se ha de tener en cuenta que si en la parametrización del origen, no se ha marcado la opción Crear Objetos en Origen o no se ha marcado la opción Copiar Lista Tablas al Destino, la tabla ibb.Cargar_Tablas_Copia_Origen estará vacía.

    Estos pasos se ejecutan si en la parametrización del destino se encuentra marcada la opción Actualizar Lista de Tablas. Si es la primera vez que se ejecuta la configuración, y la tabla ibb.Cargar_Tablas_Copia_Origen está vacía, no se hará absolutamente nada, porque la tabla ibb.Cargar_Tablas indicará qué no hay tablas a trasvasar al estar vacía. Si por el contrario, esa tabla ya contiene información, y la opción Actualizar Lista de Tablas del origen y del destino está desmarcada, dicha tabla no se actualizará, y la configuración se ejecutará con la información que dicha tabla contiene de anteriores cargas.

    • Inserta en ibb.Cargar_Tablas los registros que corresponden a aquellas tablas que están en ibb.Cargar_Tablas_Copia_Origen y no están en ibb.Cargar_Tablas y que pertenecen a la base de datos origen. Pero además, dichas tablas también han de existir en el destino. Esta inserción, incluye los campos SELECT y WHERE del origen y los campos SELECT y WHERE del destino pero obtenidos en el origen, es decir, los campos SELECT y WHERE del destino son iguales a los del origen.
    • Actualiza en ibb.Cargar_Tablas los campos SELECT y WHERE con el contenido de ibb.Cargar_Tablas_Copia_Origen para el origen en aquellas tablas que dichos campos no sean iguales. En otras palabras, en el destino, se actualiza la estructura correspondiente a la base de datos origen que ha cambiado desde la última vez que se ejecutó la configuración. Este paso sólo se ejecuta si se encuentra marcada la opción de configuración del origen Actualizar Cláusula SELECT.
    • Elimina de ibb.Cargar_Tablas aquellos registros correspondientes a tablas que han desaparecido en el ibb.Cargar_Tablas_Copia_Origen, es decir, aquellas tablas que se han eliminado en la base de datos origen desde la última vez que se ejecutó la configuración.
  • 4- Actualización del Destino con la Estructura del Destino

    Estos pasos se ejecutan si en la parametrización del destino se encuentra marcada la opción Actualizar Lista de Tablas.

    • Inserta en ibb.Cargar_Tablas los registros que corresponden a aquellas tablas que están en la base de datos destino y también están en la tabla ibb.Cargar_Tablas_Copia_Origen o bien, ibb.Cargar_Tablas_Copia_Origen está vacía. En otras palabras: Si ibb.Cargar_Tablas_Copia_Origen no está vacía, no hará nada. Pero si dicha tabla está vacía, inferirá la estructura de la base de datos origen a partir de la estructura de la base de datos destino. Tener en cuenta que se parte de la hipótesis de que ambas bases de datos tiene la misma estructura o son muy similares.
    • Actualiza en ibb.Cargar_Tablas los campos SELECT del destino con las modificaciones que haya sufrido la base de datos destino. Este paso se corresponde con la opción de configuración del destino Actualizar Cláusula SELECT
    • Elimina de ibb.Cargar_Tablas aquellos registros correspondientes a tablas que han desaparecido en el destino.
    • Actualiza el campo "ClasificacionTabla", el número de filas de cada tabla, el espacio que ocupan los datos de cada tabla y el espacio que ocupan los índices de cada tabla a partir del contenido en ibb.Cargar_Tablas_Copia_Origen.

Ventajas e Inconvenientes

La principal ventaja es que con esta estrategia, el operador puede tener centralizado en la base de datos principal todas las personalizaciones que hacen que la aplicación se ajuste a sus necesidades. Una vez realizadas, cada vez que regenere la estructura de las bases de datos de destino, se llevará consigo todas las personalizaciones, evitando así el tener que modificar el comportamiento de Insert Bulk Bestia cada vez que ejecute una carga de datos.

Por el contrario, si no puede modificar la base de datos principal, tendrá que utilizar estrategias alternativas a la hora de conservar su personalización, como por ejemplo, guardar los scripts con las personalizaciones y ejecutarlos tras una restauración de la base de datos de destino.

Esta estrategia, será en un futuro modificada, para dar cabida a otros orígenes de datos, como Oracle, por ejemplo.

Algoritmo de Copia de Datos

Los pasos que realiza Insert Bulk Bestia durante todo el proceso de ejecución de una configuración determinada son los siguientes:

  1. Comprueba la existencia de los objetos usados por Insert Bulk Bestia en el origen.
    • Si no existen, se crean.
    • Si tienen una versión inferior a la que necesita la aplicación, los actualiza si es posible, o los elimina y sustituye por los nuevos.
  2. Actualiza el contenido de de dichos objetos con la estructura de la base de datos origen.
  3. Ejecuta las Acciones Personalizadas para el Origen.
    • Ejecuta el procedimiento almacenado ibb.Cargar_Tablas_Acciones_Programables_Origen.
      • El objetivo de las acciones programadas en este procedimiento almacenado debe ser el ajuste "fino" y automático de los SELECT y WHERE para la base de datos origen, así como la realización de una clasificación automática de las tablas.
  4. Comprueba la existencia de los objetos usados por Insert Bulk Bestia en el destino.
    • Si no existen, se crean.
    • Si tienen una versión inferior a la que necesita la aplicación, los actualiza si es posible, o los elimina y sustituye por los nuevos.
  5. Trunca las tablas ibb.Cargar_Tablas_Secuencias_Copia_Origen y ibb.Cargar_Tablas_Copia_Origen en el destino.
  6. Trasvasa la información de la estructura de la base de datos origen al destino.
  7. Actualiza las tablas ibb.Cargar_Tablas_Secuencias e ibb.Cargar_Tablas del destino con la estructura del origen y del destino como se ha descrito en el apartado anterior.
  8. Para la ejecución de la configuración si lo ha indicado el usuario o ha sucedido algún evento inesperado o hay nuevas secuencias.
    • Ello permitirá al usuario, si es la primera vez que se ejecuta, revisar la idoneidad del trasvase de datos, programar las acciones personalizadas e indicar cómo se deben inicializar las nuevas secuencias.
    • Si no fuese la primera vez, no debería marcar la opción de parar la ejecución, y sólo se parará si han aparecido secuencias nuevas, para dar la oportunidad al usuario de definir su inicialización.
    • Tras la realización de las acciones oportunas, el usuario puede volver a ejecutar la configuración, esta vez ya sin marcar la opción de Stop Tras Actualizar Tablas.
  9. Ejecuta las Acciones Personalizadas Iniciales en el Destino.
    • Ejecuta el procedimiento almacenado ibb.Cargar_Tablas_Acciones_Programables_Destino_Iniciales
      • El objetivo de las acciones programadas en este procedimiento almacenado debe ser el ajuste "fino" y automático de los SELECT y WHERE para la base de datos destino, así como la realización de una clasificación automática de las tablas.
  10. Prepara la tabla ibb.Cargar_Tablas para la ejecución del trasvase de datos.
  11. Crea los objetos necesarios para desmontar y montar la estructura de la base de datos de destino.
  12. Desmonta la estructura necesaria de la base de datos destino.
    • Deshabilita los triggers.
    • Elimina las Foreing Keys.
    • Deshabilita las restricciones.
    • Vacía las tablas a cargar.
    • Elimina los índices
  13. Realiza el trasvase de datos cargando las tablas en paralelo.
  14. Monta la estructura de la base de datos que previamente había desmontado
    • Habilita las restricciones.
    • Crea los índices y estadísticas. Los puede crear en paralelo.
    • Levanta las Foreing Keys:
      • Si se indicó eliminar registros para levantarlas, eliminará lo que sea necesario para levantar las Forenig Keys.
      • Si no se marcó esa opción, dejará sin levantar aquellas Foreing Keys que no pueda.
    • Habilita los triggers.
    • Reinicia los campos identity.
    • Reinicia las secuencias.
  15. Ejecuta las Acciones Personalizadas Finales en el Destino
    • Ejecuta el procedimiento almacenado ibb.Cargar_Tablas_Acciones_Programables_Destino_Finales
      • El objetivo de las acciones programadas en este procedimiento almacenado debe ser el ajuste "fino" y automático de los datos trasvasados, como la ocultación de información confidencial, ajustes de "paths" al cambiar de entorno, etc.