it-swarm.com.de

Was passiert, wenn für SQL Server kein physischer Speicher mehr verfügbar ist?

Beim Googeln habe ich widersprüchliche Informationen gefunden.

Einige Sites geben an, dass SQL Server die bereits vorhandenen Daten in TEMPDB verschiebt, wenn kein physischer Speicher mehr für Daten vorhanden ist (siehe: SQL Server: TempDb entmystifizieren und Empfehlungen ).

Andere Sites geben jedoch an, dass das Betriebssystem die SEITENDATEI verwenden und Daten aus dem physischen Speicher in den physischen Speicher verschieben kann, wenn nicht mehr genügend physischer Speicher vorhanden ist (siehe Auslagerungsdatei für SQL Server ).

Ich frage mich, wo SQL Server Daten schreibt, wenn der physische Speicher knapp wird. Zur Tempdb oder zur OS-Seitendatei? Oder vielleicht beide?

16
RaufDBA

wenn kein physischer Speicher mehr für Daten vorhanden ist, verschiebt SQL Server die bereits vorhandenen Daten in TEMPDB

Der Artikel, auf den Sie verlinkt haben, ist bestenfalls irreführend und an einigen Stellen falsch. Ich denke, der Autor hat versucht, einige komplizierte Dinge zu stark zu vereinfachen, und ist dabei etwas zu weit gegangen.

SQL Server verschiebt auf diese Weise keine Daten aus dem Speicher (dem Pufferpool) in die Tempdb. Es wird (im Allgemeinen) eine "zuletzt verwendete" Caching-Strategie verwendet. Wenn also Speicherdruck besteht und neue Daten in den Speicher gezogen werden müssen, wirft SQL Server die LRU-Daten aus dem Pufferpool aus, um die neuen Daten aufzunehmen. Dieses Verhalten wird häufig von einem Perfmon-Zähler namens "Page Life Expectancy" (PLE) überwacht:

Die Definition von PLE ist die erwartete Zeit in Sekunden, die eine in den Pufferpool eingelesene Datendateiseite (der speicherinterne Cache von Datendateiseiten) im Speicher verbleibt, bevor sie aus dem Speicher verschoben wird, um Platz für andere Daten zu schaffen Dateiseite. Eine andere Möglichkeit, sich PLE vorzustellen, ist ein sofortiges Maß für den Druck auf den Pufferpool, um freien Speicherplatz für Seiten zu schaffen, die von der Festplatte gelesen werden. Für beide Definitionen ist eine höhere Zahl besser.

Während der Ausführung der Abfrage kann SQL Server für bestimmte Vorgänge tempdb verwenden. Dies erfolgt normalerweise, wenn die Schätzungen schlecht sind, aber ein geringer verfügbarer Speicher dieses Verhalten beeinflussen kann.

Einige der Vorgänge, die auf diese Weise in Tempdb "verschüttet" werden können, sind Hashing-Zeilen (für Verknüpfungen oder Aggregate usw.), das Sortieren von Zeilen im Speicher und das Puffern von Zeilen während der parallelen Abfrageausführung.

Benutzerabfragen können auch explizit Tempdb (mit globalen oder lokalen temporären Tabellen) und implizit Tempdb (mit Snapshot- oder Read-Commit-Snapshot-Isolationsstufen) verwenden.

Keine dieser Situationen scheint wirklich zu der von Ihnen zitierten Aussage zu passen.

wenn nicht genügend physischer Speicher vorhanden ist, kann das Betriebssystem die SEITENDATEI verwenden und Daten aus dem physischen Speicher in diesen verschieben

Dies kann definitiv passieren und liegt größtenteils außerhalb der Kontrolle von SQL Server. Es gibt einen Knopf, den Sie drehen können, um einige Arten von Paging auf Betriebssystemebene zu verhindern, nämlich das Einschalten von "Seiten im Speicher sperren" (LPIM) :

Diese Windows-Richtlinie bestimmt, welche Konten einen Prozess verwenden können, um Daten im physischen Speicher zu speichern, wodurch verhindert wird, dass das System die Daten in den virtuellen Speicher auf der Festplatte paginiert.

Was können wir also verhindern, dass es auf die Festplatte ausgelagert wird?

Vor SQL Server 2012 waren Seiten, die über eine Komponente namens "Single Page Allocator" zugewiesen wurden, im Speicher gesperrt (konnten nicht ausgelagert werden). Dies umfasste den Pufferpool (Datenbankseiten), den Prozedurcache und einige andere Speicherbereiche.

Siehe Spaß mit gesperrten Seiten, AWE, Task-Manager und dem Arbeitssatz… für Details, insbesondere den Abschnitt "4. Jetzt weiß ich, dass SQL Server auf x64" gesperrte Seiten "verwenden kann, was genau ist gesperrt? " Weitere verwandte Informationen finden Sie hier: Große SQL Server-Debatten: Seiten im Speicher sperren

In SQL Server 2012 und höher gibt es keinen "Einzelseiten-Allokator" (die Einzel- und Mehrseiten-Allokatoren wurden zusammengeführt, per Ein detaillierter Blick auf den Speicher - SQL Server 2012/2014 ) . Die Details dessen, was genau ausgelagert werden kann und was nicht, werden an keiner Stelle, die ich gesehen habe, detailliert dokumentiert. Sie können eine Abfrage so verwenden, um zu sehen, was gesperrt ist:

select osn.node_id, osn.memory_node_id, osn.node_state_desc, omn.locked_page_allocations_kb
from sys.dm_os_memory_nodes omn
inner join sys.dm_os_nodes osn on (omn.memory_node_id = osn.memory_node_id)
where osn.node_state_desc <> 'ONLINE DAC'

Gemäß demselben MS Support-Artikel können Sie auch DBCC MEMORYSTATUS Verwenden, um zu sehen, wie viel Speicher "gesperrt" ist.

Als Randnotiz können Sie im Fehlerprotokoll Hinweise darauf sehen, dass der Arbeitssatz von SQL Server vom Betriebssystem ausgelagert wird. Es wird Nachrichten geben, die so aussehen:

2019-09-02 10: 19: 27.29 spid11s Ein wesentlicher Teil des SQL Server-Prozessspeichers wurde ausgelagert. Dies kann zu einer Leistungsverschlechterung führen. Dauer: 329 Sekunden. Arbeitssatz (KB): 68780, festgeschrieben (KB): 244052, Speicherauslastung: 28%.

28
Josh Darnell

Moderne Versionen von SQL Server haben eine sehr geringe Chance, insgesamt aufzulegen. SQL Server lädt .NET Framework in seinen Adressraum und verwendet es im normalen Betrieb. Wenn sowohl der physische Speicher als auch die Auslagerungsdatei zur Neige gehen, versucht Windows, die Auslagerungsdatei zu vergrößern. Selbst wenn die Auslagerungsdatei vergrößert werden kann, ist dies kein sofortiger Vorgang, und die Speicherzuweisungen schlagen fehl, während die Auslagerungsdatei wächst. Es gibt einen Fehler im asynchronen .NET-E/A-Handler, bei dem als Antwort auf eine APC-Benachrichtigung Speicher zugewiesen wird. Wenn der Aufruf von new fehlschlägt, wird OutOfMemoryException ausgelöst. Diese Ausnahme wird im nativen Code im Taskplaner abgefangen. Die asynchrone E/A wird jedoch scheinbar nie beendet. Der Finalizer-Thread für FileStream blockiert das Warten auf das Ende der E/A, sodass der Puffer entfernt werden kann, sodass der Finalizer-Thread für immer hängen bleibt. Dies führt dazu, dass .NET Framework nach und nach immer mehr Speicher belegt, bis kein Speicher mehr zugewiesen werden kann. Zu diesem Zeitpunkt reagiert der SQL Server nicht mehr, da Winsock keine Puffer mehr zuweisen kann, sodass selbst die Administratorzugriffsverbindung unbrauchbar ist.

Ich habe tatsächlich einen Task-Scheduler-Total-Hangup in einer .NET-Anwendung erreicht, weil nicht genügend Speicher vorhanden ist. Zum Glück ist der Prozess schließlich zum Erliegen gekommen, weil OutOfMemoryException auf einen Thread geworfen wurde, der ihn nach mehreren Fehlern nicht abfing, sodass wir herausfinden konnten, was den Server tatsächlich auflegte.

Sobald ich wusste, wonach ich suchte, war es einfach, den Fehler in der statischen Analyse zu finden.

0
Joshua