Backup sehr große Tabelle

7

Ich muss bestimmte Werte einer großen Tabelle aktualisieren (für ein vermutetes Beispiel heißt sie "Ressource" und umfasst mehr als 5 Millionen Zeilen), und daher muss ich eine Sicherungskopie erstellen, bevor ich die Änderungen vornehme. Wir haben nicht genügend freien DB-Speicherplatz, um die vollständig gesicherte Tabelle zu speichern.

Welches ist der beste Weg? Gibt es eine Möglichkeit, dies durch Blöcke zu tun? Ich meine so etwas wie: Sichern der ersten 100.000 Zeilen aus der Originaltabelle, Aktualisieren dieser 100.000 Zeilen in der Originaltabelle, Löschen dieser 100.000 Zeilen aus der gesicherten Tabelle, Sichern der folgenden 100.000 Zeilen aus der Originaltabelle und analoges Vorgehen . Ist das machbar?

iL_Marto
quelle
@ George Oh, das wusste ich nicht. Danke, George.
iL_Marto
Haben Sie bereits ein Backup?
Cougar9000
Welche Version von SQL Server? Haben Sie die Backup-Komprimierung aktiviert?
Cougar9000
@ Cougar9000, nein, es gibt keine und vorhandene Sicherung und ich verwende SQL Server 2008 R2.
iL_Marto
8
Wenn die Datenbank für eine Sicherung nicht wichtig genug ist, warum ist es wichtig genug, sie zu sichern, bevor diese Änderungen vorgenommen werden? Beachten Sie auch, dass das Aktualisieren von 5 Millionen Zeilen in Ihrer Tabelle höchstwahrscheinlich zu einer bestimmten Protokollnutzung führt und wenn Sie wenig Speicherplatz in der Datenbank haben ...
Cade Roux

Antworten:

4

Zwei Gedanken kommen mir in den Sinn.

  • Wenn Sie befürchten, dass dieses Update die Tabelle möglicherweise nicht ordnungsgemäß beeinflusst, haben Sie darüber nachgedacht, das Update in eine Transaktion aufzunehmen.
  • Sie können das Update durchführen, die Daten abfragen und die Transaktion festschreiben, wenn alles in Ordnung ist. Wenn dies fehlschlägt, können Sie einen Rollback durchführen.

Alternative

Möglicherweise möchten Sie sich das BCP-Dienstprogramm ansehen , um die Tabelle in eine flache Datei außerhalb von SQL Server zu extrahieren.

Vermutlich könnten Sie den Inhalt der Tabelle an einem Ort speichern, an dem Sie nicht so stark unter Speicherdruck stehen. Wenn der Aktualisierungsvorgang fehlschlägt, können Sie versuchen, den Inhalt wieder in Ihrer Tabelle wiederherzustellen.

rauben
quelle
0

Sichern Sie keine einzelne Tabelle. Es ist normalerweise eine schlechte Idee. Sichern Sie immer die gesamte Datenbank

Als erstes. Ich gehe davon aus, dass die Datenbank nicht live ist. Andernfalls können Sie den Betrieb verlieren, wenn Sie eine Sicherung wiederherstellen.

Die Antwort, die Sie wollen, vorausgesetzt, Sie wissen, was Sie tun:

Eine einfache Möglichkeit, eine Sicherung einer Tabelle zu erstellen, besteht darin, eine andere Tabelle mit ihrem Inhalt zu erstellen:

CREATE Table tableBackup as select * from tableToBackup;

Wenn etwas schief geht, löschen Sie die Tupel aus der Originaltabelle und fügen Sie die Tupel aus der Sicherungsdatenbank ein.

Natürlich müssen Sie sich sehr bewusst sein, dass das Sichern einer einzelnen Tabelle normalerweise eine schlechte Idee ist. Normalerweise hängt die Datenbankintegrität von den Werten der gesamten Datenbank ab (z. B. kann ein Wert in einer anderen Tabelle vom Vorhandensein eines Tupels in dieser Tabelle abhängen - beispielsweise von einer Fremdschlüsselbeziehung).

Wenn zwischen der zu sichernden Tabelle und anderen Tabellen referenzielle Einschränkungen bestehen, können Sie die ursprüngliche Tabelle möglicherweise nicht mit der oben vorgeschlagenen Methode wiederherstellen.

Wenn Sie also nicht wissen, was Sie tun, sichern Sie die gesamte Datenbank und nicht die einzelne Tabelle. Überprüfen Sie die Dokumentation Ihrer Datenbank Ihrer Wahl, um zu sehen, wie dies gemacht wird.

Aaron Bertrand
quelle
2
CREATE TABLE ... AS SELECTist keine gültige SQL Server-Syntax.
Aaron Bertrand
Die Syntax für SQL Server lautet select * into schema.backuptable from schema.table;. Wie unten ausgeführt, dupliziert dies die Spaltendefinitionen und die Daten von schema.table- nicht die Einschränkungen oder Indizes oder Trigger.
Greenstone Walker
0

Hinzufügen zu dem, was @dmg gesagt hat. Das Sichern einer einzelnen Tabelle kann problematisch sein. RI beiseite, wenn zum Beispiel Ihre "große" Tabelle 90% der Datenbank ausmacht, hilft Ihnen das Sichern der Tabelle nicht wirklich viel. Wenn Sie SQL 2008 verwenden, stellen Sie sicher, dass Sie es sind compressing your backups. Sie können einen angemessenen Komprimierungsprozentsatz erzielen und möglicherweise tatsächlich eine vollständige Sicherung durchführen.

Eine andere Möglichkeit besteht darin, ein transaction logBackup zu erstellen. Dies ist, was ich normalerweise mache, wenn ich mit einer großen Datenbank arbeite, bevor ich eine Änderung vornehme. Sie sollten immer viel kleiner sein (insbesondere wenn Sie häufige Sicherungen durchführen) als die vollständige Sicherung. Und wird noch kleiner, wenn Sie sie komprimieren.

Das funktioniert jetzt nicht, wenn Ihre Datenbank auf eingestellt ist simple recovery. In diesem Fall besteht Ihre einzige andere herkömmliche Sicherungsoption darin, dies zu prüfen differential backups. Diese können tatsächlich ziemlich groß werden. Wenn Ihre letzte vollständige Sicherung jedoch kürzlich durchgeführt wurde oder Sie nur einen kleinen Prozentsatz der Datenbank ändern, ist dies möglicherweise eine praktikable Option für Sie. Wenn Ihre Datenbank jedoch auf eingestellt ist, müssen simpleSie sich möglicherweise vor Ihrer Änderung keine Sorgen darüber machen, ob sie wiederhergestellt werden kann.

Last but not least (SQL 2005 oder höher) gibt es die OUTPUTKlausel. Mit dieser praktischen kleinen Klausel können Sie die Änderungen ausgeben, die Sie während Ihres Befehls vorgenommen haben. Sie können in einer Tabellenvariablen oder Tabelle gespeichert werden. Grundsätzlich geben sie Ihnen Zugriff auf die INSERTEDund DELETEDTabellen, die Sie normalerweise nur in Triggern sehen. Ich bewege Sie können Ihre Änderungen (vorher und nachher) in einer anderen Tabelle sichern. Auf diese Weise sichern Sie nur die geänderten Zeilen und Spalten. Stellen Sie sicher, dass Sie natürlich auch Ihren Primärschlüssel angeben. Hier ist der BOL-Eintrag . Und hier ist ein Beispiel von BOL. In diesem Beispiel werden nur 4 Spalten aus 10 Datenzeilen gespeichert. Selbst wenn die Tabelle zufällig 5 oder sogar 10 mil Zeilen umfasst.

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 
OUTPUT INSERTED.EmployeeID,
       DELETED.VacationHours,
       INSERTED.VacationHours,
       INSERTED.ModifiedDate
INTO @MyTableVar;
Kenneth Fisher
quelle
0

Die Syntax zum Erstellen von Tabellen funktioniert nicht, afaik.

Der einfache Weg, eine einzelne Tabelle zu sichern, ist:

SELECT * INTO [Sicherungstabelle] FROM [Quelltabelle]

Dann können Sie [Backup-Tabelle] löschen, wenn Sie es nicht benötigen.

Sie können dies auf eine Diff-Datenbank (die sich möglicherweise auf einem Diff-Spindelsatz befindet) usw. übertragen.

Jonesome stellt Monica wieder her
quelle
0

Bisher sichern Sie anhand der gegebenen Antworten Ihre Basistabellendaten, nicht jedoch die Tabelle selbst. Die Tabelle hat viele andere Attribute, bei denen im SELECT * INTOGrunde genommen nur die Zellenwerte und die Spaltenstruktur angezeigt werden. Obwohl nicht vollständig, sind einige zusätzliche Attribute zu berücksichtigen:

  • Partitionierungsschema / Funktionen
  • Indizes
  • Fremdschlüsselbeziehungen
  • Berechtigungen auf Objektebene
  • -Erweiterte Eigenschaften
  • usw.

Dies ist eine sehr große Tabelle, daher wäre ich nicht überrascht, Partitionierung und starke Indizierung zu finden. Die beste Antwort bisher ist IMO, die gesamte Datenbank zu sichern. Wenn dies keine gute Option ist, schreiben Sie das gesamte Schema und das unterstützende Schema aus (bei Elementen, die sich wie bei der Partitionierung außerhalb der Tabelle befinden). Haben Sie eine Kopie davon, dann machen Sie eineSELECT INTO.

Natürlich empfehlen einige sehr sachkundige Personen wie Kim Tripp, Ihre Indizes hinzuzufügen und manchmal zu partitionieren, nachdem Sie die Daten gesichert haben, was wahrscheinlich ein guter Rat ist. Denken Sie daran, wenn Sie nach dem Speichern der Daten eine Partition ausführen, sollten Sie eine Prüfbedingung verwenden, um sicherzustellen, dass die Partition entfernt wird. Das ist etwas zu prüfen, wenn Sie es tatsächlich konfiguriert sehen.

Ali Razeghi
quelle
0

Sie können eine Sicherung der vorhandenen Tabelle allein in eine new_table aufnehmen und Ihre Tabelle aktualisieren. Wenn etwas schief geht, können Sie Ihre Sicherungstabelle immer zurücksetzen.

Ex:

-- SCRIPT TO BACKUP A TABLE
SELECT * INTO <NEW_TABLE> FROM CURRENT_TABLE

Das Sichern der einzelnen Tabelle ist viel weniger als das Sichern der gesamten Datenbank.

Wenn alles gut geht, können Sie die fallen lassen <NEW_TABLE>.

JaMeEL
quelle
Die Frage lautet: "Wir haben nicht genügend freien DB-Speicherplatz, um die vollständig gesicherte Tabelle zu speichern." Was Sie also vorschlagen, wird hier nicht funktionieren.
Mat