Verkürzte 200-GB-Tabelle, aber nicht freigegebener Speicherplatz

23

Ich habe nur noch 2 GB, daher muss ich diese Verlaufstabelle entfernen. Diese Tabelle ist jetzt leer, aber der Datenbankspeicherplatz wurde nicht freigegeben. Und die Datenbankdatei ist 320GB.

Lucas Rodrigues Sena
quelle
Ich habe einige Replikationsspuren in der Datenbank gefunden, die die Protokollgröße drastisch erhöhen und das Löschen oder Verkleinern verhindern.
Lucas Rodrigues Sena

Antworten:

25

Wenn Sie auf den tatsächlichen Verbrauch der Datenbankdatei auf dem Volume verweisen, wird dies von SQL Server nicht automatisch verarbeitet . Nur weil Sie Daten aus der Datenbank entfernt haben, bedeutet dies nicht, dass die Datenbankdateien nur auf die vorhandenen Daten verkleinert werden.

Was würden Sie werden suchen, wenn Sie haben Platz auf dem Datenträger zurückzugewinnen, wäre mit der bestimmten Datei schrumpfen DBCC SHRINKFILE. In Bezug auf diese Dokumentation sollten einige bewährte Methoden erwähnt werden:

Best Practices

Berücksichtigen Sie die folgenden Informationen, wenn Sie eine Datei verkleinern möchten:

  • Ein Verkleinerungsvorgang ist am effektivsten nach einem Vorgang, bei dem viel ungenutzter Speicherplatz erstellt wird, z.

  • Für die meisten Datenbanken ist freier Speicherplatz für den täglichen Betrieb erforderlich. Wenn Sie eine Datenbank wiederholt verkleinern und feststellen, dass die Datenbankgröße erneut zunimmt, ist dies ein Hinweis darauf, dass der verkleinerte Speicherplatz für den regulären Betrieb erforderlich ist. In diesen Fällen ist das wiederholte Verkleinern der Datenbank eine Verschwendung.

  • Bei einem Verkleinerungsvorgang bleibt der Fragmentierungsstatus von Indizes in der Datenbank nicht erhalten, und die Fragmentierung wird im Allgemeinen bis zu einem gewissen Grad erhöht. Dies ist ein weiterer Grund, die Datenbank nicht wiederholt zu verkleinern.

  • Verkleinern Sie mehrere Dateien in derselben Datenbank nacheinander anstatt gleichzeitig. Konflikte in Systemtabellen können zu Verzögerungen aufgrund von Blockierungen führen.

Beachten Sie auch:

DBCC SHRINKFILE Operationen können zu jedem Zeitpunkt des Prozesses angehalten werden, und alle abgeschlossenen Arbeiten bleiben erhalten.

Es gibt sicherlich ein paar Dinge zu beachten, und ich empfehle Ihnen, in Paul Randals Blog-Post nachzuschlagen, was passiert, wenn Sie diese Operation ausführen.

Der erste Schritt wäre auf jeden Fall, zu überprüfen, wie viel Speicherplatz und freier Speicherplatz Sie tatsächlich ersetzen können, sowie den belegten Speicherplatz in den Dateien:

use AdventureWorks2012;
go

;with db_file_cte as
(
    select
        name,
        type_desc,
        physical_name,
        size_mb = 
            convert(decimal(11, 2), size * 8.0 / 1024),
        space_used_mb = 
            convert(decimal(11, 2), fileproperty(name, 'spaceused') * 8.0 / 1024)
    from sys.database_files
)
select
    name,
    type_desc,
    physical_name,
    size_mb,
    space_used_mb,
    space_used_percent = 
        case size_mb
            when 0 then 0
            else convert(decimal(5, 2), space_used_mb / size_mb * 100)
        end
from db_file_cte;
Thomas Stringer
quelle
6

Dies ist ein normales Verhalten, wenn Sie eine Tabelle abschneiden und dabei mehr als 128 Speicherbereiche als Per Books Online entfernen

Wenn Sie große Indizes löschen oder neu erstellen oder große Tabellen löschen oder kürzen, verschiebt das Datenbankmodul die eigentlichen Seitenfreigaben und die zugehörigen Sperren, bis eine Transaktion festgeschrieben wurde. Diese Implementierung unterstützt sowohl Autocommit- als auch explizite Transaktionen in einer Mehrbenutzerumgebung und gilt für große Tabellen und Indizes, die mehr als 128 Speicherbereiche verwenden.

Das Datenbankmodul vermeidet die Zuordnungssperren, die zum Löschen großer Objekte erforderlich sind, indem der Prozess in zwei separate Phasen aufgeteilt wird: logisch und physisch.

In der logischen Phase werden die vorhandenen Zuordnungseinheiten, die von der Tabelle oder dem Index verwendet werden, für die Freigabe markiert und gesperrt, bis die Transaktion festgeschrieben wird. Wenn ein Clustered-Index gelöscht wird, werden die Datenzeilen kopiert und dann in neue Zuordnungseinheiten verschoben, die entweder als neu erstellter Clustered-Index oder als Heap im Speicher erstellt wurden. (Bei einer Indexwiederherstellung werden die Datenzeilen ebenfalls sortiert.) Bei einem Rollback muss nur diese logische Phase zurückgesetzt werden.

Die physische Phase tritt auf, nachdem die Transaktion festgeschrieben wurde. Die für die Freigabe markierten Zuordnungseinheiten werden stapelweise physisch gelöscht. Diese Abbrüche werden in kurzen Transaktionen verarbeitet, die im Hintergrund ausgeführt werden, und erfordern nicht viele Sperren.

Da die physische Phase nach dem Festschreiben einer Transaktion auftritt, wird der Speicherplatz der Tabelle oder des Index möglicherweise weiterhin als nicht verfügbar angezeigt. Wenn dieser Speicherplatz erforderlich ist, damit die Datenbank wächst, bevor die physische Phase abgeschlossen ist, versucht das Datenbankmodul, Speicherplatz aus Zuordnungseinheiten wiederherzustellen, die für die Freigabe markiert sind. Verwenden Sie die Katalogsicht sys.allocation_units, um den aktuell von diesen Zuordnungseinheiten verwendeten Speicherplatz zu ermitteln.

Verzögerte Löschvorgänge geben den zugewiesenen Speicherplatz nicht sofort frei und verursachen zusätzliche Gemeinkosten im Datenbankmodul. Daher werden Tabellen und Indizes, die 128 oder weniger Speicherbereiche verwenden, gelöscht, abgeschnitten und wie in SQL Server 2000 neu erstellt. Dies bedeutet, dass sowohl die logische als auch die physische Phase stattfinden, bevor die Transaktion festgeschrieben wird.

Sie müssten warten und natürlich die Datei manuell verkleinern , um Speicherplatz freizugeben. Erwähnenswert ist auch, dass das Verkleinern eine logische Fragmentierung verursacht und vermieden werden sollte, es sei denn, Ihr Bedarf ist groß. Man müsste einigermaßen zwischen Schrumpfen und Fragmentieren ausbalancieren. Es ist besser, sich selbst zu fragen, ob ein Schrumpfen das Problem in Anbetracht des Szenarios, in dem die Daten sowieso wieder zunehmen, tatsächlich lösen würde.

Verwenden Sie die folgende Abfrage, um zu überprüfen, wie viel freier Speicherplatz in der Datenbank vorhanden ist

SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;
Shanky
quelle
6

Zusätzlich zu den Antworten von Tom und Shanky funktioniert die DBCC SHRINKFILE möglicherweise nicht, wenn Ihre Datenbank LOB / BLOB-Daten enthält. In diesem Fall haben Sie zwei Möglichkeiten, je nachdem, ob Sie die Datenbank offline schalten können oder nicht. Wenn Sie die Datenbank offline schalten können, müssen Sie die Daten aus und wieder einkopieren, um den leeren Bereich zu entfernen. Sie können dies auf eine der folgenden Arten erreichen:

  1. Verwenden einer SELECT INTO- Anweisung, um die gesamte Tabelle in eine neue Tabelle zu übertragen. Löschen Sie die ursprüngliche Tabelle, führen Sie DBCC SHRINKFILE aus . Benennen Sie die neue Tabelle in den ursprünglichen Tabellennamen um.
  2. Kopieren Sie die Tabelle im einheitlichen Modus mit bcp , löschen Sie sie , führen Sie DBCC SHRINKFILE aus , erstellen Sie eine Tabelle und schreiben Sie die Daten in die Tabelle.
  3. Verschieben Sie mit Export / Import alle Daten in eine neue Datenbank, löschen Sie die vorhandene Datenbank und benennen Sie die neue Datenbank in den ursprünglichen Datenbanknamen um.

Wenn Sie die Datenbank nicht offline schalten können, können Sie den Befehl DBCC SHRINKFILE mit der Option EMPTYFILE verwenden .

Details zum Offline-Kopieren: http://support.microsoft.com/kb/324432/en-us

Aktuelle Informationen zur EMPTYFILE-Option http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx

Stacylaray
quelle