Was ist die beste Methode, um nur einige Tabellen in einer Testdatenbank aus der Produktion zu aktualisieren?

12

Ich habe eine sehr große Produktionsdatenbank und eine sehr große Testumgebungsdatenbank in SQL Server 2008R2. Beide Datenbanken haben eine ähnliche Tabellenstruktur, jedoch unterschiedliche Benutzer / Anmeldungen / Berechtigungen / Rollen.

Ich muss nur ein paar Tabellen in der Testdatenbank regelmäßig aus der Produktion aktualisieren, etwa einmal im Monat.

Die derzeitige Art, wie ich das vorhabe, ist

  1. Verwenden Sie das Dienstprogramm BCP, um einen Export der benötigten Tabellen aus der Produktion durchzuführen.
  2. Kopieren Sie die BCP-Exportdatei auf den Testserver
  3. Deaktivieren Sie die Indizes und Einschränkungen für alle Tabellen, die ich in Test aktualisiere
  4. Kürzen Sie die Testdatenbanktabellen
  5. Laden Sie die Daten mithilfe von BCP zurück in die Testdatenbanktabellen.
  6. Erstellen Sie die Indizes neu und aktivieren Sie die Einschränkungen in Test erneut

Dies alles scheint ein wenig zu kompliziert für eine so kleine Aufgabe. Es sieht auch so aus, als würde es eine Menge Redo erzeugen (im T-Log). Gibt es eine bessere Möglichkeit, dies zu tun?

Eine andere Möglichkeit, die ich mir vorgestellt habe, besteht darin, ein Backup aus der Produktion in der Testumgebung wiederherzustellen. Mein Problem ist jedoch, dass ein vollständiges Backup sehr umfangreich ist und nicht alle Tabellen aktualisiert werden müssen, sondern nur einige wenige. -und auch die Benutzer und Sicherheit in der Produktionsdatenbank unterscheidet sich vom Test. Das würde durch die Sicherheitseinstellungen in der Produktionsdatenbank überschrieben, wenn ich die gesamte Datenbank wiederherstelle.

Eric Larson
quelle
Dieser Ansatz könnte auch eine Untersuchung wert sein: sqlperformance.com/2012/08/t-sql-queries/… und sqlperformance.com/2013/04/t-sql-queries/…
Aaron Bertrand

Antworten:

4

Es gibt 2 Methoden, die Ihren Anforderungen entsprechen:

(Hinweis: Wenn die Tabellen mit Fremdschlüsseln referenziert werden, können Sie sie nicht verwenden TRUNCATE. Sie müssen in Blöcken löschen . Alternativ können Sie alle Indizes + Fremdschlüssel löschen und Daten laden und anschließend neu erstellen.)

  • BCP OUT und BULK INSERT INTO Zieldatenbank .

    • Stellen Sie sicher, dass Sie die Testdatenbank in den einfachen / massenprotokollierten Wiederherstellungsmodus versetzen.
    • Enable Trace Flag 610 - Minimal protokollierte Einfügungen in indizierte Tabellen.

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

-

  • Methode 2: SSIS - Meine bevorzugte Methode in diesem Fall.

    • Keine Bereitstellung auf der Festplatte erforderlich. Die gesamte Verarbeitung erfolgt im Speicher.
    • Sie können das SSIS-Paket jeden Monat mithilfe des SQL Agent-Jobs planen, um die Aktualisierung der Tabellen von PROD auf den TEST-Server zu automatisieren.
    • Wählen Sie die Option " FAST LOAD "
    • Stellen Sie sicher, dass Sie pro Chargennummer eine gute Anzahl von Zeilen auswählen.

Referenz: Das Handbuch zum Laden von Daten und meine Antwort für - In Tabelle einfügen Wählen Sie * aus Tabelle vs. Bulk-Insert

Kin Shah
quelle
1
SSIS ist definitiv der richtige Weg. Datenpumpen ist das, wofür es entwickelt wurde.
Steve Mangiameli
3

Es ist nicht erforderlich, Sicherungen und Wiederherstellungen durchzuführen oder externe Prozesse (z. B. BCP) aufzurufen / zu koordinieren oder gar mit SSIS zu arbeiten (sehr leistungsfähig, sehr cool, aber wenn ich es vermeiden kann, werde ich es auf jeden Fall tun :). All dies können Sie bequem mit T-SQL erledigen, in einer gespeicherten Prozedur, die Sie über SQL Agent planen können, oder in einem Skript, das Sie einmal im Monat ausführen (obwohl das Einfügen in eine Prozedur und das Planen auf lange Sicht weniger arbeitsintensiv ist Lauf). Wie? Durch die Verwendung von SQLCLR für den Zugriff auf die SqlBulkCopyKlasse in .NET, da es sich im Wesentlichen um BCP handelt, ohne den Aufwand beim Aufrufen von BCP. Sie können dies selbst codieren: Es gibt kein super kompliziertes Setup oder ähnliches wie dasSqlBulkCopyclass erledigt fast alles für Sie (Sie können die Stapelgröße festlegen, ob Trigger ausgelöst werden sollen oder nicht usw.). Oder, wenn Sie mit dem Kompilieren und Bereitstellen einer Assembly nicht zu verwirren wollen, können Sie eine vorgefertigte verwenden SQLCLR gespeicherte Prozedur wie DB_BulkCopy , die Teil der ist SQL # SQLCLR Bibliothek (die ich bin der Autor, aber diese gespeicherte Verfahren ist in der Free-Version). Ich beschreibe dies ausführlicher, einschließlich eines Beispiels für die Verwendung von DB_BulkCopy , in der folgenden Antwort:

Importieren Sie Daten aus einer Datenbank in ein anderes Skript

Wenn nicht klar ist, wo dies in Ihrem aktuellen Plan platziert werden soll, würden Sie Folgendes tun:

  • Entfernen Sie die Schritte 1 und 2 (woo hoo!)
  • Ersetzen Sie Schritt 5 mit einem EXECvon DB_BulkCopy oder was auch immer Sie es nennen , wenn Sie es selbst Code, der nur die Daten von Punkt A zu Punkt B bewegt

Es sollte auch darauf hingewiesen werden, dass SqlBulkCopyund DB_BulkCopy :

  • Kann jede Ergebnismenge akzeptieren: Egal, ob es sich um SELECT oder EXEC einer gespeicherten Prozedur handelt
  • sind sehr einfach zu aktualisieren, wenn Schemaänderungen an einer dieser Tabellen vorgenommen werden. ÄNDERN Sie einfach die Abfrage in Ihrer gespeicherten Prozedur, die diese gespeicherte SQLCLR-Prozedur aufruft
  • Ermöglichen Sie das erneute Zuordnen der Felder, falls dies jemals benötigt wird

UPDATE in Bezug auf minimal protokollierte Vorgänge über SqlBulkCopy

Es ist möglich, minimal protokollierte Vorgänge abzurufen, aber Sie sollten wissen:

Solomon Rutzky
quelle