it-swarm.com.de

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

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

Ich muss nur einige Tabellen in der Testdatenbank regelmäßig aus der Produktion aktualisieren, ungefähr einmal im Monat.

Die aktuelle Art, wie ich das vorhabe, ist

  1. Verwenden Sie das BCP-Dienstprogramm, um die benötigten Tabellen aus der Produktion zu exportieren.
  2. Kopieren Sie die bcp-Exportdatei auf den Testserver
  3. Deaktivieren Sie Indizes und Einschränkungen für alle Tabellen, die ich in Test aktualisiere
  4. Schneiden Sie die Testdatenbanktabellen ab
  5. Laden Sie Daten mit BCP zurück in Testdatenbanktabellen.
  6. erstellen Sie Indizes neu und aktivieren Sie Einschränkungen in Test erneut

Das alles scheint für eine so kleine Aufgabe etwas zu kompliziert. Es scheint auch so, als würde es viel Wiederholung erzeugen (im T-Log). Gibt es einen besseren Weg, dies zu tun?

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

12
Eric Larson

Es gibt zwei Methoden, die Ihren Anforderungen entsprechen:

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

  • BCP OUT und BULK INSERT INTO Zieldatenbank .

    • Stellen Sie sicher, dass Sie die Testdatenbank in den einfachen/massenprotokollierten Wiederherstellungsmodus versetzen.
    • Trace-Flag 610 aktivieren - minimal protokollierte Einfügungen in indizierten 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 eines SQL Agent-Jobs planen, um die Aktualisierung von Tabellen von PROD auf den TEST-Server zu automatisieren.
    • Wählen Sie die Option " FAST LOAD "
    • Stellen Sie sicher, dass Sie eine gute Zeile pro Chargennummer auswählen (Wenn Sie zu hoch wählen, kommt es zu einer Sperreneskalation - halten Sie diese unter 5 KB).

Referenz: The Data Loading Performance Guide und meine Antwort für - In Tabelle einfügen Wählen Sie * aus Tabelle vs. Masseneinfügung

4
Kin Shah

Es besteht keine Notwendigkeit, Sicherungen und Wiederherstellungen durchzuführen oder externe Prozesse (d. H. BCP) aufzurufen/zu koordinieren oder sogar mit SSIS zu spielen (sehr leistungsfähig, sehr cool, aber wenn ich es vermeiden kann, werde ich es auf jeden Fall tun :). All dies können Sie bequem von T-SQL aus in einer gespeicherten Prozedur erledigen, die Sie über SQL Agent planen können, oder in einem Skript, das Sie einmal im Monat ausführen (obwohl es auf lange Sicht weniger Arbeit ist, es in einem Prozess zu haben und zu planen Lauf). Wie? Durch die Verwendung von SQLCLR für den Zugriff auf die Klasse SqlBulkCopy in .NET, da es sich im Wesentlichen um BCP handelt, ohne den ganzen Aufwand, BCP aufzurufen. Sie können dies selbst codieren: Es gibt kein super kompliziertes Setup oder ähnliches, da die SqlBulkCopy -Klasse fast alles für Sie erledigt (Sie können die Stapelgröße festlegen, ob Trigger ausgelöst werden sollen oder nicht usw.). Wenn Sie sich nicht mit dem Kompilieren und Bereitstellen einer Assembly herumschlagen möchten, können Sie eine vorgefertigte gespeicherte SQLCLR-Prozedur wie DB_BulkCopy verwenden Teil der SQL # SQLCLR-Bibliothek (deren Autor ich bin, aber diese gespeicherte Prozedur befindet sich in der kostenlosen Version). Ich beschreibe dies ausführlicher, einschließlich eines Beispiels für die Verwendung von DB_BulkCopy in der folgenden Antwort:

Daten aus einer Datenbank in ein anderes Skript importieren

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 durch ein EXEC von DB_BulkCopy oder wie auch immer Sie es nennen, wenn Sie es selbst codieren, wodurch nur die Daten von Punkt A verschoben werden zu Punkt B.

Es sollte auch darauf hingewiesen werden, dass SqlBulkCopy und DB_BulkCopy :

  • kann jede Ergebnismenge akzeptieren: spielt keine Rolle, ob es sich um eine SELECT- oder EXEC-Datei 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 die Neuzuordnung der Felder, falls dies jemals benötigt wird

UPDATE zu minimal protokollierten Vorgängen über SqlBulkCopy

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

  • Sie müssen die Option TableLock Bulk Copy verwenden
  • Laden Sie dabei für Tabellen mit Clustered-Indizes zuerst die Daten in [tempdb] und dann die bestellte Einfügung in das Ziel vornehmen. Daher entsteht eine zusätzliche Last, sowohl hinsichtlich der physischen E/A für Tempdb (Daten- und Protokolldateien) als auch hinsichtlich der Sortieroperation (aufgrund des ORDER BY, die erforderlich ist, um die minimal protokollierten Vorgänge abzurufen)
  • Einige Testergebnisse hier: Whitepaper: Leistung von SqlBulkCopy
  • Einige Testergebnisse hier: Fehlerbehebung bei SqlBulkCopy führt keine minimale Protokollierung durch
3
Solomon Rutzky