¿Cuál es el mejor método para actualizar solo unas pocas tablas dentro de una base de datos de prueba de producción?


12

Tengo una base de datos de producción muy grande y una base de datos de entorno de prueba muy grande en SQL Server 2008R2. Ambas bases de datos tienen una estructura de tabla similar pero diferentes usuarios / inicios de sesión / permisos / roles.

Necesito actualizar solo unas pocas tablas de la base de datos de prueba periódicamente desde la producción, aproximadamente una vez al mes.

La forma actual en que planeo hacer esto es

  1. Use la utilidad BCP para exportar las tablas que necesito de Producción.
  2. Copie el archivo de exportación bcp en el servidor de prueba
  3. Deshabilite índices y restricciones en todas las tablas que estoy actualizando en Prueba
  4. Truncar las tablas de la base de datos de prueba
  5. Vuelva a cargar los datos en las tablas de la base de datos de prueba con BCP
  6. reconstruir índices y volver a habilitar restricciones en Prueba

Todo esto parece demasiado complicado para una tarea tan pequeña. También parece que generaría mucho rehacer (en el t-log) ¿Hay una mejor manera de hacer esto?

Otra forma en que pensé hacer esto es restaurar una copia de seguridad de Producción en el entorno de prueba, pero el problema que tengo es que una copia de seguridad completa sería bastante grande y no necesito actualizar todas las tablas, solo unas pocas. -y también los usuarios y la seguridad en la base de datos de producción es diferente de la prueba. Eso sería sobrescrito por la configuración de seguridad en la base de datos de producción si restauro toda la base de datos.


Respuestas:


4

Existen 2 métodos que se adaptarán a sus necesidades:

(Nota: si la clave externa hace referencia a las tablas, entonces no podrá usarlas TRUNCATE. Debe eliminarlas en fragmentos . Alternativamente, puede eliminar todos los índices + claves externas y cargar datos y luego volver a crearlos).

  • BCP OUT e BULK INSERT INTO en la base de datos de destino .

    • Asegúrese de poner la base de datos de prueba en modo de recuperación simple / de registro masivo.
    • Habilite Trace Flag 610: inserciones mínimamente registradas en tablas indexadas.

      /************************************************************************************************************************************************
      Author      :   KIN SHAH    *********************************************************************************************************************
      Purpose     :   Move data from one server to another*********************************************************************************************
      DATE        :   05-28-2013  *********************************************************************************************************************
      Version     :   1.0.0   *************************************************************************************************************************
      RDBMS       :   MS SQL Server 2008R2 and 2012   *************************************************************************************************
      *************************************************************************************************************************************************/
      
      -- save below output in a bat file by executing below in SSMS in TEXT mode
      -- clean up: create a bat file with this command --> del D:\BCP_OUT\*.dat 
      
      select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" '-- path to BCP.exe
              +  QUOTENAME(DB_NAME())+ '.'                                    -- Current Database
              +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
              +  QUOTENAME(name)  
              +  ' out D:\BCP_OUT\'                                           -- Path where BCP out files will be stored
              +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
              +  REPLACE(name,' ','') 
              + '.dat -T -E -SSERVERNAME\INSTANCE -n'                         -- ServerName, -E will take care of Identity, -n is for Native Format
      from sys.tables
      where is_ms_shipped = 0 and name <> 'sysdiagrams'                       -- sysdiagrams is classified my MS as UserTable and we dont want it
      and schema_name(schema_id) <> 'some_schema_exclude'                     -- Optional to exclude any schema 
      order by schema_name(schema_id)                         
      
      
      
      --- Execute this on the destination server.database from SSMS.
      --- Make sure the change the @Destdbname and the bcp out path as per your environment.
      
      declare @Destdbname sysname
      set @Destdbname = 'destination_database_Name'               -- Destination Database Name where you want to Bulk Insert in
      select 'BULK INSERT '                                       -- Remember Tables **must** be present on destination Database
              +  QUOTENAME(@Destdbname)+ '.'
              +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.' 
              +  QUOTENAME(name) 
              + ' from ''D:\BCP_OUT\'                             -- Change here for bcp out path
              +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
              +  REPLACE(name,' ','') 
              +'.dat'' 
              with (
              KEEPIDENTITY,
              DATAFILETYPE = ''native'',  
              TABLOCK
              )'  + char(10) 
              + 'print ''Bulk insert for '+REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'+  REPLACE(name,' ','')+' is done... '''+ char(10)+'go' 
      from sys.tables
      where is_ms_shipped = 0 and name <> 'sysdiagrams'           -- sysdiagrams is classified my MS as UserTable and we dont want it
      and schema_name(schema_id) <> 'some_schema_exclude'         -- Optional to exclude any schema 
      order by schema_name(schema_id)

-

  • Método 2: SSIS: mi método preferido en este caso.

    • No se requiere puesta en escena en el disco. Todo el procesamiento se realiza en la memoria.
    • Puede programar el paquete SSIS utilizando el trabajo del agente sql cada mes para automatizar la actualización de tablas desde PROD al servidor de PRUEBA.
    • Elija la opción " CARGA RÁPIDA "
    • Asegúrese de elegir una buena fila por número de lote (si elige demasiado alto, habrá una escalada de bloqueo, manténgalo por debajo de 5K)

Referencia: La Guía de rendimiento de carga de datos y mi respuesta para - Insertar en la tabla seleccionar * de la tabla vs inserción masiva


1
SSIS es definitivamente el camino a seguir aquí. El bombeo de datos es para lo que fue diseñado.
Steve Mangiameli

3

No es necesario hacer copias de seguridad y restauraciones, ni llamar / coordinar procesos externos (es decir, BCP), ni siquiera meterse con SSIS (muy potente, muy bueno, pero si puedo evitarlo, ciertamente lo haré :). Puede manejar todo esto desde la comodidad de T-SQL, en un procedimiento almacenado que puede programar a través del Agente SQL, o un script que ejecuta una vez al mes (aunque tenerlo en un proceso y programación es menos trabajo a largo plazo correr). ¿Cómo? Al usar SQLCLR para acceder a la SqlBulkCopyClase en .NET, ya que es esencialmente BCP sin todo el alboroto de llamar a BCP. Puede codificar esto usted mismo: no hay una configuración súper complicada ni nada como elSqlBulkCopyLa clase se encarga de casi todo por usted (puede establecer el tamaño del lote, disparar o no disparadores, etc.). O, si no desea meterse con la compilación y la implementación de un ensamblaje, puede usar un procedimiento almacenado SQLCLR precompilado como DB_BulkCopy, que es parte de la biblioteca SQL # SQLCLR (de la que soy autor, pero esta almacenada procedimiento está en la versión gratuita). Describo esto con más detalle, incluido un ejemplo de uso de DB_BulkCopy , en la siguiente respuesta:

Importar datos de una base de datos a otro script

Si no está claro dónde colocar esto en su plan actual, haría lo siguiente:

  • Elimina los pasos 1 y 2 (¡woo hoo!)
  • Reemplazar el paso 5 con una EXECde DB_BulkCopy o como se llame si el código usted mismo, que solo mueve los datos desde el punto A al punto B.

Además, debe señalarse que SqlBulkCopyy DB_BulkCopy :

  • puede aceptar cualquier conjunto de resultados: no importa si es un SELECT o EXEC de un procedimiento almacenado
  • son muy fáciles de actualizar cuando se realizan cambios de esquema en cualquiera de estas tablas; simplemente ALTERE la consulta en su Procedimiento almacenado que llama a este Procedimiento almacenado SQLCLR
  • permitir reasignar los campos, si es necesario

ACTUALIZACIÓN sobre operaciones mínimamente registradas a través de SqlBulkCopy

Es posible obtener operaciones mínimamente registradas, pero debe saber:

  • Debe usar la opción de Copia masiva de TableLock
  • Hacer esto, para las tablas con índices agrupados, primero cargará los datos [tempdb]y luego realizará la inserción ordenada en el destino. Por lo tanto, se incurre en una carga adicional, tanto en términos de E / S física a tempdb (datos y archivos de registro) como de la operación de clasificación (debido a lo ORDER BYque se requiere para obtener las operaciones mínimamente registradas)
  • Algunos resultados de las pruebas aquí: Libro blanco: rendimiento de SqlBulkCopy
  • Algunos resultados de las pruebas aquí: Solución de problemas SqlBulkCopy no hace un registro mínimo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.