Verkleinern Sie eine Datenbank unter ihre ursprüngliche Größe


10

Ich habe eine SQL Server 2005-Entwicklerdatenbank, die eine 30-GB-Kopie von Live ist. Wir haben einige Daten gelöscht, die in dev nicht benötigt werden, wodurch der verwendete Speicherplatz für Datendateien auf 20 GB reduziert wird. Wir haben also ungefähr 33% ungenutzt.

Ich muss den Speicherplatz zurückfordern, damit wir eine zweite Entwicklungsdatenbank auf dem Server haben können (basierend auf der reduzierten Version). Ich kann den Speicherplatz jedoch nicht zurückfordern. Ich habe Folgendes getan:

  • Die anfängliche Größe der Datei SMS2_Databeträgt 30 GB.

    DBCC SHRINKFILE (N'SMS2_Data' , 0, TRUNCATEONLY)

    gefolgt von

    DBCC SHRINKFILE (N'SMS2_Data' , 19500)

Keine Freude. Ich habe versucht, ein Backup zu erstellen, eine neue Datenbank mit einer geringen Anfangsgröße zu erstellen und dann wiederherzustellen. Keine Freude, da die Anfangsgröße überschrieben wird. Habe auch versucht:

ALTER DATABASE SMS2HazSub MODIFY FILE (NAME = 'SMS2_Data', SIZE = 20000) 

Dies irrte und sagte:

DATEI ÄNDERN fehlgeschlagen. Die angegebene Größe ist kleiner als die aktuelle Größe.

Ich habe 20800 ausprobiert und bin dann weiter auf 29000 (29 GB) gestiegen, und ich kann es immer noch nicht ändern.

Habe den Schrumpf gemacht und dann den Wiederherstellungsmodus von FULLnach SIMPLEund wieder zurück geändert . Keine Freude.

Ich dachte, das hätte mit einigen TEXTFeldern zu tun . Wir haben ungefähr 6 im ganzen System. Als Test habe ich sie alle gelöscht und dann die Datei verkleinert und immer noch keine Änderung vorgenommen.

Die einzige verbleibende Option besteht darin, die Daten erneut in eine andere Datenbank zu importieren. Dies ist nicht praktikabel, da dies auf der Live-DB erfolgen müsste, die ein zu hohes Risiko birgt. Wir holen uns halb regelmäßig eine Kopie der Live-Datenbank und überschreiben dev / test. Wir haben ungefähr 500 Tische. Ich möchte einen Weg, der nicht das Risiko birgt, Daten in eine neue Datenbank zu exportieren.

Ich habe versucht, die Daten in eine andere Datei zu verschieben, und es wurden alle bis auf 5% der Daten kopiert. Dies hat mich veranlasst, alle Textspalten zu löschen.

Der Server befindet sich im Kompatibilitätsmodus 90, ist jedoch SP2. Ich habe jetzt die folgenden drei Schritte ausgeführt: Alle Tabellen neu indizieren, Datenbank sichern, Datei verkleinern, Datenbank verkleinern. Immer noch keine Freude.

EXECUTE sp_spaceused kehrt zurück:

database_name   database_size   unallocated space
SMS2Tests       31453.94 MB     13903.16 MB

reserved     data         index_size   unused
16545568 KB  10602264 KB  4254360 KB   1688944 KB

Antworten:


3

Wie einige Leute bereits erwähnt haben, können Sie eine neue Datenbank erstellen und Inhalte aus der alten Datenbank "kopieren". Dies wäre die beste Option für Sie. Ich habe jedoch bemerkt, dass Sie es ziemlich regelmäßig tun möchten. Ihre beste Option ist also Redgate Data Compare und Redgate Compare . Beide sind Teil des Redgate SqlToolbelt- Pakets.

Also, was Sie tun:

  1. Erstellen Sie eine leere Datenbank mit kleiner Anfangsgröße.
  2. Verwenden Sie Redgate Compare, um die Datenbankstruktur, Funktionen usw. von der alten Datenbank zu kopieren
  3. Verwenden Sie Redgate Data Compare, um Daten aus der alten Datenbank in eine neue zu kopieren
  4. Sie arbeiten an der Entwicklungsdatenbank und führen dann jederzeit entweder nur einen Datenvergleich durch und aktualisieren die Entwicklungsdatenbank regelmäßig. Wenn Sie Änderungen an der Datenbank vornehmen, können Sie diese Änderungen mithilfe von Redgate Compare bereitstellen und anschließend Redgate Data Compare ausführen.

Was mit Data Compare gut ist, ist, dass nach dem Kopieren dieser 30 GB Daten (Sie können dies nur mit einigen Tabellen beginnen) nach einer Weile nur einige Änderungen und nicht die gesamten 30 GB Daten neu verglichen werden müssen. Dies bedeutet, dass beide Datenbanken wesentlich weniger betroffen sind als durch normales Kopieren.


2

Ein paar Möglichkeiten hier.

Sind Sie zunächst in SQL 2005 SP3 oder höher? Einige haben SHRINKFILE-Probleme in früheren Versionen gemeldet (siehe http://www.sqlservercentral.com/Forums/Topic981292-146-6.aspx#bm985164 ).

Zweitens können Sie überprüfen, ob die Datenbank auf Kompatibilität mit Modus 90 und nicht auf Modus 80 eingestellt ist? Dies war anscheinend ein Problem mit SQL 2000, aber die Einschränkung wurde in SQL 2005 aufgehoben. Wenn Ihre Datenbank weiterhin auf Kompatibilität mit Modus 80 eingestellt ist, ist dies möglicherweise immer noch ein Problem.

Drittens könnte dies ein Problem mit LOB-Daten sein (Text, ntext, varchar (max)). Siehe Paul Randalls ausgezeichneten Artikel hier

Ich gehe davon aus, dass Sie verstehen, was SHRINKing wirklich tut, und dass es sich negativ auf Ihre Leistung auswirken kann:

  • SHRINK verschiebt Seiten blind vom Ende der Datei zum Anfang
  • Als solches kann es Indizes schrecklich fragmentieren, was zu erheblichen Leistungsproblemen führen kann
  • Da es sich um einen so datenintensiven Vorgang handelt, kann das Schrumpfen erheblich dauern

Normalerweise würde ich empfehlen, dem Schrumpfen eine vollständige Neuindizierung zu folgen (wodurch ein Teil des gerade freigegebenen Speicherplatzes zurückgewonnen wird), aber es hört sich nicht so an, als könnten Sie überhaupt an diesen Punkt gelangen.

Wenn Sie sich Ihre Schrumpf-SPID im Aktivitätsmonitor ansehen, scheint sie etwas zu tun? (E / A- und CPU-Zähler ändern sich) Oder ist es blockiert? Das einzige andere, woran ich denken kann, ist, wenn die Datenbank andere Aktivitäten enthält, die den Schrumpf blockieren. Stellen Sie sicher, dass derzeit keine anderen aktiven Spids die Datenbank verwenden.

Es ist auch eine gute Idee, während dieses Vorgangs in den einfachen Wiederherstellungsmodus zu wechseln, um zu verhindern, dass das Protokoll zu stark wächst.


1

SHRINKDATABASE verkleinert die Datenbank nur (bestenfalls) auf ihre MinSize, so dass Ihnen das nicht hilft.

Wenn Sie versuchen, die DATEI über die SSMS-Benutzeroberfläche mit den Standardeinstellungen zu verkleinern, wird 'DBCC SHRINKFILE (N'MyDB', 0, TRUNCATEONLY) 'verwendet. Dieser Befehl verkleinert die Datei (bestenfalls) nur bis zum zuletzt zugewiesenen Umfang.

Wenn Sie die Datei unterhalb der MinSize verkleinern möchten, ändern Sie einfach den Parameter DBCC SHRINKFILEvon 0 auf die Größe, auf die Sie versuchen möchten, die Datei in MB zu verkleinern. Eine Zahl ungleich Null weist SHRINKFILE an, die Datei nach Möglichkeit auf diese Größe zu verkleinern. So DBCC SHRINKFILE('MyDB', 300, TRUNCATEONLY)wird die Datei auf 300 MB schrumpfen , wenn die Datenbank Speicherplatz verfügt.

Sie können die MinSize sehen, indem Sie Folgendes ausführen:

DBCC TRACEON(3604)
go
DBCC PAGE('MyDB', 1, 0, 3) with tableresults
go

MinSize in MB wird wie folgt berechnet: (MinSize * 8) / 1024


0

Wenn Sie dies wirklich tun möchten:

  • Stellen Sie den Wiederherstellungsmodus auf einfach ein
  • Beachten Sie: DBCC SHRINKDATABASE (MyDatabase, TRUNCATEONLY);

0

Wenn Sie beispielsweise 20003 (mb) tatsächliche Daten in der Datenbank haben, wäre "SIZE = 20000" zu klein. Versuchen Sie es mit 21000 oder 25000, um zu sehen, ob das funktioniert. (Und denken Sie daran, 1 GB = 1024 MB.)


0

Versuchen

DBCC SHRINKDATABASE (N'SMS2_Data' , 0)

Ich habe dies in einer SQL 2005-Datenbank verwendet, die ich hier habe, und der zugewiesene Speicherplatz für die Datendatei stieg von 10,2 GB auf 3 GB.

Zu Ihrer Information, dies ist ein langwieriger Prozess, der für meine Datenbank etwas mehr als 19 Minuten gedauert hat.


ps Gerade überprüft und das Wiederherstellungsmodell für meine Datenbank ist auf Einfach eingestellt.

Das hat keinen Unterschied gemacht, ich bin mir ziemlich sicher, dass das dasselbe ist, was über das Frontend erledigt wird.

0

Ich gehe davon aus, dass Sie eine einzelne Datenbankdatei mit dem logischen Namen SMS2_Data haben. Sie haben auch eine oder mehrere Transaktionsprotokolldateien in der Datenbank.

Sie haben eine Herausforderung, die auf der aktuellen Kopie der Datenbank nicht behoben werden kann. Die wichtige Information, die Sie angeben, ist, dass die ursprüngliche Größe der Datenbankdatei 30 GB beträgt. Leider kann diese Datei nicht kleiner als ihre ursprüngliche Größe verkleinert werden.

Wie Sie bereits erfahren haben, geben SHRINKDB und SHRINKFILE Ihnen nicht das, was Sie wollen. Diese Befehle folgen der Regel, dass nicht kleiner als die ursprüngliche Größe verkleinert werden kann. Sie können eine Datenbank also nur auf die ursprüngliche Größe und nicht kleiner verkleinern.

Das Sichern und Wiederherstellen der Datenbank in einer vorhandenen, kleineren Datenbank funktioniert ebenfalls nicht. Wenn Sie eine Datenbankwiederherstellung durchführen, werden die Datenbankdateien auf die Dateigröße zurückgesetzt, die sie während der Sicherung hatten. Das Wiederherstellungsmodell (einfach, vollständig usw.) hat für dieses Problem keine Relevanz.

Und noch ein letzter Punkt mit schlechten Nachrichten. Sie können der Datenbank weitere kleinere Datenbankdateien hinzufügen, alle Daten aus der 30-GB-Datei übertragen und dann löschen. Leider funktioniert dies auch nicht, da Sie die ursprüngliche Datei nicht aus der Datenbank löschen können.

Die beste Lösung besteht also darin, die Daten in eine andere Datenbank zu kopieren. Sie haben hier einige Optionen, die Sie vielleicht bereits kennen. Der erste Schritt besteht darin, eine neue Datenbank mit einer Größe zu erstellen, die kleiner als die Datengröße ist. Anschließend können Sie die Datenbankgröße auf die erforderliche Größe erweitern.

Sie können SSIS als eine Möglichkeit betrachten, die Daten von einer Datenbank in die andere zu übertragen. Sie finden eine Kopierdatenbankaufgabe, die Ihnen weiterhilft. Sie können die folgenden Schritte ausführen:

  1. Erstellen Sie eine neue Datenbank mit einer kleineren Größe als die Quelldatenbank
  2. Richten Sie das SSIS-Paket mit der Aufgabe "Datenbank übertragen" ein. Stellen Sie die Aufgabe für die Verwendung der Online-Übertragung ein.
  3. Führen Sie das SSIS-Paket aus.
  4. Das SSIS-Paket kann die Datenbankgröße ändern, um sie an die Größe der Quellendatenbank anzupassen. Verkleinern Sie diese Datenbank, da sie eine kleinere ursprüngliche Dateigröße hat.

Weitere Informationen zur Aufgabe der SSIS- Übertragungsdatenbank finden Sie hier .


0

Nicht genutzter Speicherplatz in der Datenbank ist normal.
Wenn Sie viele große Datensätze haben (z. B. lange Zeichenfolgen), ist möglicherweise nicht viel Speicherplatz auf den Datenseiten vorhanden (da ein Datensatz normalerweise nicht zwischen den Seiten aufgeteilt ist).
Eine andere Sache ist ein Füllfaktor - anfänglich werden Clustered-Indizes nicht zu 100% voll erstellt, um Seitenaufteilungen (eine teure Operation) beim nachfolgenden Einfügen zu vermeiden.
Wenn viele Daten aus der Datenbank gelöscht wurden, wird der zuvor von diesen Daten belegte Speicherplatz nicht automatisch zurückgefordert - er bleibt der Tabelle zugeordnet.

Versuchen Sie, DBCC DBREINDEX (table_name, '', 100)jede Tabelle in Ihrer Datenbank aufzurufen. Dadurch werden alle Indizes mit einem Füllfaktor von 100% neu erstellt, damit die Daten so kompakt wie möglich platziert werden. Versuchen Sie dann erneut, die Datenbank zu verkleinern.


0

Ich habe festgestellt, dass das Verkleinern einer SQL Server-Datenbank problematisch sein kann. Es fühlt sich an, als müsste man eine Lied- und Tanzroutine machen.

Dies ist der Prozess, den ich normalerweise durchlaufe:

Backup Shrink-Datenbank Backup Shrink-Protokoll und Datenbankdateien getrennt. Backup Wiederholen, bis es endgültig schrumpft.

Ich musste diesen Vorgang einige Male bis zu dreimal durchführen, damit er endlich funktioniert. Wir hatten eine Datenbank mit einer Größe von über 68 GB und einem zu 98% nicht genutzten Speicherplatz. Ich habe diese Song-and-Dance-Routine mehrmals durchlaufen, aber sie ist schließlich auf unter 1 GB geschrumpft.


0

Ich hätte versucht, die anfängliche Größe der MDF-Datei zuerst auf 29.000 MB und dann auf 28.000 MB zu reduzieren, um den Treffer zu erkennen.

Es ist nicht zu erwarten, dass die Größe der Datenbankdatei durch Löschen von 30% der Daten um 30% reduziert wird.

Sie können schätzen, wie viel nicht genutzten Speicherplatz in Ihrer Datenbank durch

execute sp_spaceused

im Kontext Ihrer Datenbank (verwenden Sie Ihren Dateinamen;)
Können Sie das Ergebnis der Ausführung veröffentlichen?


Update:
Ich habe meine verwandte Frage darauf gepostet:


Das hat nicht so gut funktioniert. 13903.16mb nicht zugeordneter Speicherplatz. Unbenutzter Index 1688944 KB
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.