Heute habe ich festgestellt, dass die Festplatte, auf der meine Datenbanken gespeichert sind, voll ist. Das ist schon mal passiert, normalerweise ist die Ursache ziemlich offensichtlich. Normalerweise gibt es eine fehlerhafte Abfrage, die zu großen Verschüttungen von Tempdb führt, die zunehmen, bis die Festplatte voll ist. Diesmal war es weniger offensichtlich, was passierte, da tempdb nicht die Ursache für das volle Laufwerk war, sondern die Datenbank selbst.
Die Fakten:
- Die übliche Datenbankgröße beträgt ca. 55 GB, sie ist auf 605 GB angewachsen.
- Protokolldatei hat normale Größe, Datendatei ist riesig.
- Datendatei verfügt über 85% verfügbaren Speicherplatz (ich interpretiere dies als "Luft": Speicherplatz, der verwendet wurde, aber freigegeben wurde. SQL Server reserviert den gesamten Speicherplatz, sobald er zugewiesen wurde).
- Die Tempdb-Größe ist normal.
Ich habe die wahrscheinliche Ursache gefunden. Es gibt eine Abfrage, die viel zu viele Zeilen auswählt (eine fehlerhafte Verknüpfung führt zur Auswahl von 11 Milliarden Zeilen, von denen einige Hunderttausend erwartet werden). Dies ist eine SELECT INTO
Abfrage, die mich gefragt hat, ob das folgende Szenario hätte passieren können:
- SELECT INTO wird ausgeführt
- Zieltabelle wird erstellt
- Daten werden beim Auswählen eingefügt
- Die Festplatte füllt sich und der Einsatz schlägt fehl
- SELECT INTO wird abgebrochen und zurückgesetzt
- Beim Rollback wird Speicherplatz freigegeben (bereits eingefügte Daten werden entfernt), SQL Server gibt den freigegebenen Speicherplatz jedoch nicht frei.
In dieser Situation hätte ich jedoch nicht erwartet, dass die von der erstellte Tabelle SELECT INTO
noch vorhanden ist. Sie sollte durch das Rollback gelöscht werden. Ich habe das getestet:
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
Das führt zu:
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
Die Zieltabelle existiert jedoch. Die eigentliche Abfrage wurde jedoch nicht in einer expliziten Transaktion ausgeführt. Kann das die Existenz der Zieltabelle erklären?
Sind die hier skizzierten Annahmen korrekt? Ist das ein wahrscheinliches Szenario?