Gemeinsamer Arbeitsbereich

Wer die tempdb füllt, steht in einer einzigen Abfrage

Temporäre Objekte, interne Arbeitsdateien und der Versionsspeicher teilen sich denselben Platz. Ohne diese Unterscheidung sucht man an der falschen Stelle nach der Ursache.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Seit 1997 am Markt Kleine Gruppen Präsenz und Live-Online Zertifizierte Trainer
Worum es geht

Ein Neustart räumt die tempdb auf und verdeckt damit die Ursache

Die tempdb wird bei jedem Start des Datenbankmoduls neu erzeugt. Ein Neustart wirkt deshalb sofort: Die Dateien sind wieder klein, der Fehler ist weg, und alle gehen zur Tagesordnung über. Zwei Tage später ist derselbe Zustand wieder da, weil nichts an der Ursache geändert wurde.

Verstärkt wird das durch eine Verwechslung. Zwei völlig verschiedene Probleme werden beide als tempdb-Problem gemeldet: der Platzmangel und die Zugriffskonkurrenz auf Verwaltungsseiten. Für Letztere gibt es seit SQL Server 2019 die speicheroptimierten tempdb-Metadaten, und diese Einstellung wird regelmäßig gegen ein Platzproblem eingesetzt, wo sie nichts ausrichtet.

Teuer wird der Platzmangel, weil er nicht die Abfrage trifft, die ihn verursacht hat. Läuft die tempdb voll, scheitern die Abfragen, die zufällig als Nächstes Platz anfordern, häufig also Berichte oder Nachtläufe, die mit dem Verursacher nichts zu tun haben. Die Fehlermeldung zeigt damit systematisch auf das falsche Ende.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Symptom, Ursache, Lösung

Symptom, Ursache, Lösung

Symptom

Die tempdb wächst über Nacht auf ein Vielfaches und ist morgens wieder klein.

Ursache

Der Wartungsplan baut Indizes neu auf. Mit SORT_IN_TEMPDB landen die Zwischenergebnisse der Sortierung als interne Objekte in der tempdb, und ein Neuaufbau mit ONLINE erzeugt zusätzlich Zeilenversionen im Versionsspeicher.

Lösung

Den Platzbedarf des Wartungsfensters messen und die tempdb darauf auslegen, statt sie wachsen zu lassen. Wo möglich reorganisieren statt neu aufbauen, große Tabellen einzeln und über mehrere Nächte verteilt bearbeiten und den Neuaufbau bei Bedarf fortsetzbar gestalten.

Symptom

Der Platz schwindet, obwohl kaum Abfragen laufen und niemand temporäre Tabellen anlegt.

Ursache

Der Versionsspeicher wächst. Unter Zeilenversionierung bleiben alle Versionen erhalten, solange die älteste offene Transaktion sie noch sehen könnte. Eine einzige vergessene offene Transaktion hält damit stundenlang alles fest.

Lösung

Über sys.dm_tran_active_snapshot_database_transactions die älteste Transaktion samt Laufzeit und Sitzung ermitteln und sie beenden. Danach die Anwendung prüfen, denn eine Transaktion, die eine Stunde offen steht, ist fast immer ein nicht geschlossener Verbindungspfad im Code.

Symptom

Mitten am Tag melden mehrere Abfragen gleichzeitig, in der tempdb sei kein Platz mehr.

Ursache

Eine einzelne Abfrage lagert eine Sortierung oder einen Hashvorgang auf die Platte aus, weil die zugeteilte Speichermenge zu klein war. Das passiert bei veralteten Statistiken oder bei Filtern, deren Selektivität der Planer falsch einschätzt.

Lösung

Die laufenden Speicherzuteilungen über sys.dm_exec_query_memory_grants ansehen und die Abfrage mit der größten Differenz zwischen angefordertem und benötigtem Speicher herausgreifen. Die dauerhafte Lösung sind aktuelle Statistiken und ein passender Index, nicht mehr Plattenplatz.

Symptom

Eine der tempdb-Dateien ist voll, die anderen sind fast leer.

Ursache

Die Dateien haben unterschiedliche Größen oder unterschiedliche Wachstumseinstellungen. SQL Server verteilt neue Zuweisungen proportional zum freien Platz und bevorzugt damit die Datei mit dem meisten freien Raum, bis sich das Ungleichgewicht verstärkt.

Lösung

Alle Datendateien auf dieselbe Anfangsgröße und dasselbe Wachstum in Megabyte setzen, nicht in Prozent. Als Anhaltspunkt für die Anzahl gilt die Zahl der logischen Prozessoren, höchstens aber acht Dateien.

Symptom

Nach einem Neustart ist alles in Ordnung, nach zwei Tagen ist der Zustand zurück.

Ursache

Die tempdb wird beim Start neu aus der Vorlage erzeugt und hat danach wieder ihre Anfangsgröße. Der Neustart beseitigt das Symptom, nicht die Ursache, und erzeugt zusätzlich Aufwand, weil die Dateien anschließend wieder auf die Betriebsgröße wachsen müssen.

Lösung

Die Anfangsgröße auf den gemessenen Höchstbedarf setzen, damit die Dateien nach dem Start sofort die richtige Größe haben. Dazu gehört die Berechtigung zum sofortigen Initialisieren von Dateien für das Dienstkonto, sonst blockiert jedes Wachstum, bis der Platz vollständig genullt ist.

Was die tempdb belegt und wann sie wieder leer ist

  1. 01 Benutzerobjekte sind temporäre Tabellen, Tabellenvariablen und Cursor.
  2. 02 Interne Objekte entstehen bei Sortierungen, Hashvorgängen und Spools.
  3. 03 Der Versionsspeicher hält Zeilenversionen für Leseoperationen fest.
  4. 04 Ein Indexneuaufbau mit SORT_IN_TEMPDB belastet gleich zwei davon.
  5. 05 Beim Neustart des Datenbankmoduls wird die tempdb komplett neu erzeugt.
Was du mitnimmst

Danach findest du den Verursacher, statt Platz nachzuschieben

Die Diagnose folgt einer festen Reihenfolge: erst die Art des Verbrauchs bestimmen, dann die Sitzung oder Transaktion dahinter, und erst zum Schluss über Dateigrößen und Autogrowth reden. Die dauerhafte Maßnahme liegt meist außerhalb der tempdb.

Den Verbrauch nach Art aufteilen

sys.dm_db_file_space_usage weist die belegten Seiten getrennt nach Benutzerobjekten, internen Objekten und Versionsspeicher aus. Diese drei Zahlen entscheiden, in welche Richtung du weitersuchst.

Die Sitzung hinter temporären Objekten finden

sys.dm_db_session_space_usage und sys.dm_db_task_space_usage zeigen je Sitzung und je Aufgabe, wie viele Seiten belegt und wieder freigegeben wurden. Damit ist der Verursacher benannt, nicht nur die Menge.

Den Versionsspeicher an der ältesten Transaktion festmachen

Wächst der Versionsspeicher, hält irgendwo eine Transaktion Zeilenversionen fest. sys.dm_tran_active_snapshot_database_transactions nennt sie samt Laufzeit, und meist ist es eine Verbindung, die die Anwendung nicht geschlossen hat.

Interne Objekte als Folge zu kleiner Speicherzuteilungen lesen

Wenn Sortierungen und Hashvorgänge auf die Platte auslagern, wachsen die internen Objekte. Ursache ist fast immer eine zu niedrige Schätzung im Ausführungsplan, sichtbar über sys.dm_exec_query_memory_grants und die Warnung im Plan.

Tabellenvariablen nicht für speicherresident halten

Auch eine Tabellenvariable wird in der tempdb angelegt. Der Unterschied zu einer temporären Tabelle liegt in Transaktionsverhalten und Statistiken, nicht im Speicherort.

Dateien gleich groß und gleich wachsend halten

SQL Server verteilt Zuweisungen proportional zum freien Platz. Sind die Datendateien unterschiedlich groß, landet fast alles in einer einzigen, und die läuft voll, während daneben Platz frei ist.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt

Drei Verbraucher, ein Datenbereich

Benutzerobjekte sind alles, was jemand ausdrücklich anlegt: temporäre Tabellen mit einer oder zwei Rauten, Tabellenvariablen, Cursor und die Ergebnisse von Tabellenwertfunktionen. Der verbreitete Glaube, eine Tabellenvariable liege im Arbeitsspeicher und eine temporäre Tabelle auf der Platte, stimmt nicht. Beide werden in der tempdb angelegt, die Unterschiede liegen im Transaktionsverhalten, in der Statistikpflege und in der Parallelisierbarkeit.

Interne Objekte legt der Server selbst an, ohne dass jemand sie sieht. Dazu gehören Arbeitstabellen für Spools und Cursor, Arbeitsdateien für Hashvorgänge und Zwischenergebnisse von Sortierungen, etwa beim Erstellen eines Index mit SORT_IN_TEMPDB oder bei einer Abfrage mit GROUP BY, deren Zwischenergebnis nicht in den zugeteilten Speicher passt.

Der Versionsspeicher hält Zeilenversionen fest, die für Leseoperationen unter Zeilenversionierung gebraucht werden, außerdem für Onlinevorgänge an Indizes, für mehrere aktive Ergebnismengen auf einer Verbindung und für Trigger, die nach der Änderung ausgeführt werden. Er ist der einzige der drei, dessen Größe nicht von der aktuellen Last abhängt, sondern von der ältesten noch offenen Transaktion.

Den Verursacher in drei Abfragen einkreisen

Die erste Abfrage geht auf sys.dm_db_file_space_usage in der tempdb und summiert user_object_reserved_page_count, internal_object_reserved_page_count, version_store_reserved_page_count und unallocated_extent_page_count. Multipliziert mit acht Kilobyte je Seite ergibt das vier Zahlen, die zusammen den gesamten Datenbereich beschreiben. Welche der ersten drei die größte ist, bestimmt den weiteren Weg.

Dominieren Benutzerobjekte, geht es weiter mit sys.dm_db_session_space_usage und sys.dm_db_task_space_usage. Beide führen Zuweisungen und Freigaben getrennt, sodass sich der aktuelle Verbrauch je Sitzung ausrechnen lässt. Über sys.dm_exec_requests und sys.dm_exec_sql_text kommst du von der Sitzungsnummer zum tatsächlichen Anweisungstext.

Dominiert der Versionsspeicher, ist sys.dm_tran_active_snapshot_database_transactions die richtige Sicht, weil sie zu jeder Transaktion die verstrichene Zeit liefert. Sortier nach dieser Spalte, die oberste Zeile ist in der Regel die Ursache. Ab SQL Server 2017 zeigt sys.dm_tran_version_store_space_usage zusätzlich, aus welcher Datenbank die Versionen stammen, und das ist auf einer Instanz mit vielen Datenbanken die entscheidende Information.

Interne Objekte sind der Abdruck einer zu kleinen Speicherzuteilung

Für jede Abfrage, die sortieren oder hashen muss, reserviert SQL Server vor dem Start eine Speichermenge. Die Größe beruht auf der geschätzten Zeilenzahl. Schätzt der Optimierer zu niedrig, reicht die Zuteilung nicht, und der Rest der Arbeit wandert als internes Objekt in die tempdb. sys.dm_exec_query_memory_grants stellt für laufende Abfragen angeforderten, tatsächlich zugeteilten und idealerweise benötigten Speicher nebeneinander. Liegt der ideale Wert weit über dem zugeteilten, hast du den Kandidaten gefunden.

Im Ausführungsplan hinterlässt derselbe Vorgang eine Warnung am Sortier- oder Hashoperator. Wer nicht danebensitzen will, während es passiert, schneidet die Ereignisse sort_warning und hash_warning über eine Sitzung der erweiterten Ereignisse mit und hat danach eine Liste der betroffenen Anweisungen. Die Ursache ist fast immer eine Schätzung, die weit danebenliegt, meist wegen veralteter Statistiken oder wegen eines Filters, dessen Selektivität sich nicht abschätzen lässt.

Dateien, Autogrowth und die Ablaufverfolgungsflags, die man nicht mehr braucht

Für die Anzahl der Datendateien gilt eine einfache Regel: so viele wie logische Prozessoren, höchstens jedoch acht. Bleibt danach noch Zuweisungskonkurrenz messbar, erhöht man in Vierer-Schritten. Alle Dateien brauchen dieselbe Anfangsgröße und dasselbe Wachstum, sonst greift die proportionale Verteilung und die größte Datei bekommt fast alles ab.

Zwei Ablaufverfolgungsflags tauchen in älteren Anleitungen immer noch auf. Flag 1117 sorgte dafür, dass alle Dateien einer Dateigruppe gemeinsam wachsen, Flag 1118 dafür, dass Zuweisungen in vollen Blöcken erfolgen. Beides ist seit SQL Server 2016 für die tempdb das Standardverhalten, die Flags sind dort ohne Wirkung. Wer sie noch gesetzt hat, kann sie entfernen.

Das Wachstum selbst gehört auf einen festen Wert in Megabyte, nicht auf einen Prozentsatz, denn prozentuales Wachstum wird mit jeder Runde größer und blockiert entsprechend länger. Wichtiger ist ohnehin, dass es gar nicht erst dazu kommt: Setz die Anfangsgröße auf den gemessenen Höchstbedarf. Damit das Wachstum der Datendateien im Ernstfall nicht den Betrieb anhält, braucht das Dienstkonto das Recht zum sofortigen Initialisieren von Dateien, sonst wird jeder neu belegte Bereich vor der Nutzung mit Nullen überschrieben. Für die Protokolldatei gilt das nur eingeschränkt: Bis SQL Server 2019 wurde sie immer vollständig genullt, ab SQL Server 2022 gilt die schnelle Initialisierung dort für Wachstumsschritte bis 64 Megabyte.

Die dauerhaften Maßnahmen liegen meist außerhalb der tempdb

Wenn interne Objekte den Platz füllen, ist die Ursache eine Abfrage, deren Speicherbedarf falsch geschätzt wurde. Aktuelle Statistiken, ein passender Index und das Vermeiden von Funktionen auf der Filterspalte wirken hier stärker als jede Vergrößerung der Dateien. Dasselbe gilt für Sortierungen: Ein Index, der die Sortierreihenfolge bereits liefert, macht die Auslagerung überflüssig.

Wenn Benutzerobjekte dominieren, lohnt der Blick in die gespeicherten Prozeduren. Häufig wird eine große Tabelle vollständig in eine temporäre Tabelle kopiert, um danach darauf zu filtern. Das Filtern vor dem Kopieren spart den Platz vollständig. Ebenso häufig bleiben temporäre Tabellen in langlaufenden Prozeduren bis zum Ende bestehen, obwohl sie nach dem dritten von zwanzig Schritten nicht mehr gebraucht werden.

Beim Versionsspeicher ist die Maßnahme fast immer eine Änderung in der Anwendung, nämlich Transaktionen nur so lange offen zu halten, wie sie wirklich brauchen. Eine Transaktion, die auf eine Benutzereingabe oder auf eine Antwort eines fremden Dienstes wartet, ist der klassische Fall. SQL Server 2025 bringt hier zwei Ergänzungen, die den Betrieb entspannen: eine Begrenzung des tempdb-Verbrauchs je Arbeitslast über die Ressourcenverwaltung und die beschleunigte Datenbankwiederherstellung auch für die tempdb selbst. Letztere bringt allerdings einen zusätzlichen dauerhaften Versionsspeicher mit, dessen Platzbedarf in die Auslegung gehört.

Dazu passende Kurse

Wer eine Instanz verantwortet, sollte diese Sichten kennen, bevor die Datei voll ist, und dafür gibt es die SQL-Server-Kurse für Administration und Wartung .

Wissen prüfen

Wie sicher bist du beim Thema wirklich?

Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.

Super Schulung, in der der Trainer auch auf eigene Fragestellungen eingegangen ist.
PostgreSQL Datenbankentwicklung Aufbaukurs
Super Grundlagenschulung mit allen wichtigen Punkten und hilfreichen Tipps!
PostgreSQL Einführung und SQL Grundlagenkurs
Schön, sich 5 Tage ungestört mit Postgres beschäftigen zu können.
PostgreSQL für Administratoren Grundkurs

Häufige Fragen

Kann ich die tempdb im laufenden Betrieb verkleinern?
DBCC SHRINKFILE funktioniert grundsätzlich, scheitert aber oft, weil belegte Bereiche am Ende der Datei liegen und nicht verschoben werden können. Zuverlässig wird die tempdb erst beim nächsten Neustart des Datenbankmoduls wieder klein, weil sie dabei komplett neu erzeugt wird. Deshalb ist die Anfangsgröße die eigentliche Stellschraube und nicht das nachträgliche Verkleinern.
Helfen speicheroptimierte tempdb-Metadaten gegen Platzmangel?
Nein, das sind zwei verschiedene Probleme. Diese Einstellung aus SQL Server 2019 beseitigt die Zugriffskonkurrenz auf die Verwaltungstabellen, die beim schnellen Anlegen und Löschen vieler temporärer Objekte entsteht. Am belegten Platz ändert sie nichts. Erkennbar ist die Zugriffskonkurrenz an Wartetypen, die mit PAGELATCH beginnen, nicht an einer vollen Datei.
Wie groß sollte die tempdb sein?
So groß wie der gemessene Höchstbedarf unter deiner Last, einschließlich des Wartungsfensters. Dafür lässt du die Dateien einmal wachsen, protokollierst über einen typischen Zeitraum die Belegung mitsamt Indexpflege und setzt die Anfangsgröße anschließend auf diesen Höchstwert mit etwas Reserve. Eine allgemeine Prozentangabe vom Datenvolumen führt in die Irre, weil der Bedarf an den Abfragen hängt und nicht an der Datenmenge.
Warum trifft der Fehler immer die falsche Abfrage?
Weil die Meldung erst dort erscheint, wo Platz angefordert und nicht mehr gefunden wird. Der Verursacher hat seinen Platz zu diesem Zeitpunkt längst belegt und läuft möglicherweise ohne Fehler weiter. Deshalb hilft es nicht, die meldende Abfrage zu untersuchen, sondern nur die Aufteilung nach Verbrauchsart zum Zeitpunkt des Fehlers.
Persönlich für dich da

Deine Ansprechpartner

Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.

Yves Hoppe

Yves Hoppe

Weiterbildung & Beratung

Hilft dir, aus dem Datenbanken-Programm den passenden Kurs für deinen Stand zu finden.

Norbert Jansen

Norbert Jansen

Beratung & Inhouse

Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.

Eine tempdb, die man ausgelegt hat statt nachzuziehen

Wie sich Verbrauch messen, Verursacher benennen und Dateien richtig dimensionieren lassen, gehst du bei cmt an einer laufenden Instanz durch, mit den Abfragen, die du danach im Betrieb behältst.