Qual è il metodo migliore per aggiornare solo alcune tabelle all'interno di un database di test dalla produzione?


12

Ho un database di produzione molto grande e un database di ambiente di test molto grande in SQL Server 2008R2. Entrambi i database hanno una struttura di tabella simile ma utenti / accessi / autorizzazioni / ruoli diversi.

Devo aggiornare periodicamente solo alcune tabelle nel database di test dalla produzione, circa una volta al mese.

Il modo in cui sto pianificando di farlo è

  1. Utilizzare l'utilità BCP per eseguire un'esportazione delle tabelle necessarie dalla produzione.
  2. Copia il file di esportazione bcp sul server di prova
  3. Disabilita indici e vincoli su tutte le tabelle che sto aggiornando in Test
  4. Troncare le tabelle del database di test
  5. Caricare nuovamente i dati nelle tabelle del database di test utilizzando BCP.
  6. ricostruire gli indici e riattivare i vincoli in Test

Tutto questo sembra un po 'troppo complicato per un compito così piccolo. Sembra anche che genererebbe molta ripetizione (nel registro t) Esiste un modo migliore per farlo?

Un altro modo in cui ho pensato di farlo è ripristinare un backup da Production nell'ambiente di test, ma il problema che ho è che un backup completo sarebbe abbastanza grande e non ho bisogno di aggiornare tutti i tavoli, solo alcuni- -e anche gli utenti e la sicurezza nel database di produzione sono diversi dai test. Ciò verrebbe sovrascritto dalle impostazioni di sicurezza nel database di produzione se ripristino l'intero database.


Questo approccio potrebbe anche valere la pena di essere analizzato: sqlperformance.com/2012/08/t-sql-queries/… e sqlperformance.com/2013/04/t-sql-queries/…
Aaron Bertrand

Risposte:


4

Esistono 2 metodi adatti alle tue esigenze:

(Nota: se le tabelle fanno riferimento a chiave esterna, non sarà possibile utilizzarle TRUNCATE. È necessario eliminare in blocchi . In alternativa, è possibile eliminare tutti gli indici + chiavi esterne e caricare i dati, quindi ricrearli).

  • BCP OUT e BULK INSERT nel database di destinazione .

    • Assicurarsi di impostare il database di test in modalità di ripristino semplice / con registrazione di massa.
    • Abilita Trace Flag 610: inserimenti con registrazione minima in tabelle indicizzate.

      /************************************************************************************************************************************************
      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)
      

-

  • Metodo 2: SSIS - Il mio metodo preferito in questo caso.

    • Nessuna stadiazione su disco richiesta. Tutta l'elaborazione viene eseguita in memoria.
    • È possibile pianificare il pacchetto SSIS utilizzando il processo sql agent ogni mese per automatizzare l'aggiornamento delle tabelle dal server PROD al TEST.
    • Scegli l' opzione " FAST LOAD "
    • Assicurati di scegliere una buona riga per numero di lotto (se scegli troppo alto, ci sarà un escalation di blocco - mantienilo inferiore a 5K)

Riferimento: la Guida alle prestazioni del caricamento dei dati e la mia risposta per - Inserisci nella tabella selezionare * dalla tabella rispetto all'inserimento di massa


1
SSIS è sicuramente la strada da percorrere qui. Il pumping dei dati è ciò che è stato progettato per fare.
Steve Mangiameli,

3

Non è necessario eseguire backup e ripristini o chiamare / coordinare processi esterni (ad es. BCP) o persino pasticciare con SSIS (molto potente, molto interessante, ma se posso evitarlo, lo farò sicuramente :). Puoi gestire tutto ciò comodamente da T-SQL, in una procedura memorizzata che puoi pianificare tramite SQL Agent o uno script che esegui una volta al mese (anche se averlo in un proc e la pianificazione è meno lavoro a lungo correre). Come? Usando SQLCLR per accedere alla SqlBulkCopyClasse in .NET in quanto è essenzialmente BCP senza tutto il trambusto di chiamare BCP. Puoi codificarlo tu stesso: non esiste una configurazione super complicata o altro comeSqlBulkCopyLa classe si occupa di quasi tutto per te (puoi impostare la dimensione del lotto, se attivare o meno i grilletti, ecc.). In alternativa, se non si desidera scherzare con la compilazione e la distribuzione di un assembly, è possibile utilizzare una stored procedure SQLCLR preconfigurata come DB_BulkCopy che fa parte della libreria SQL # SQLCLR (di cui sono l'autore, ma questa è archiviata la procedura è nella versione gratuita). Lo descrivo in modo più dettagliato, incluso un esempio dell'uso di DB_BulkCopy , nella seguente risposta:

Importa i dati da un database a un altro script

Se non è chiaro dove inserirlo nel piano corrente, si dovrebbe fare quanto segue:

  • Rimuovi i passaggi 1 e 2 (woo hoo!)
  • Sostituisci il passaggio 5 con uno EXECdi DB_BulkCopy o come lo chiami se lo codifichi tu stesso, il che sposta i dati dal punto A al punto B.

Inoltre, va sottolineato che SqlBulkCopye DB_BulkCopy :

  • può accettare qualsiasi set di risultati: non importa se si tratta di un SELECT o EXEC di una procedura memorizzata
  • sono molto facili da aggiornare quando vengono apportate modifiche allo schema in una di queste tabelle; basta ALTER la query nella Stored Procedure che chiama questa SQLCLR Stored Procedure
  • consentire la rimappatura dei campi, se mai necessario

AGGIORNAMENTO relativo alle operazioni minimamente registrate tramite SqlBulkCopy

È possibile ottenere operazioni minimamente registrate, ma è necessario sapere:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.