Co dzieje się, gdy nie ma dostępnej pamięci fizycznej dla programu SQL Server?


16

Podczas wyszukiwania w Google znalazłem sprzeczne informacje.

Niektóre witryny stwierdzają, że gdy nie ma już fizycznej pamięci na dane, wówczas SQL Server przenosi już istniejące dane do TEMPDB (patrz: SQL Server: Demystifying TempDb i zalecenia ).

Ale inne witryny stwierdzają, że gdy nie ma wystarczającej ilości pamięci fizycznej, system operacyjny może użyć PLIKU STRONY i przenieść do niego dane z pamięci fizycznej (zobacz Plik strony dla SQL Server ).

Zastanawiam się, gdzie SQL Server zapisuje dane, gdy zabraknie pamięci fizycznej? Aby tempdb lub do pliku strony systemu operacyjnego? A może oboje?

Odpowiedzi:


28

gdy nie ma już fizycznej pamięci dla danych, SQL Server przenosi już istniejące dane do TEMPDB

Artykuł, do którego linkujesz, jest co najmniej wprowadzający w błąd i w niektórych miejscach jest niepoprawny. Myślę, że autor próbował nadmiernie uprościć niektóre skomplikowane rzeczy, a robiąc to posunął się trochę za daleko.

SQL Server nie przenosi danych z pamięci (puli buforów) do tempdb w ten sposób. Wykorzystuje strategię buforowania „ostatnio używaną” (ogólnie), więc jeśli występuje presja pamięci, a nowe dane muszą zostać wciągnięte do pamięci, SQL Server wykopie dane LRU z puli buforów, aby pomieścić nowe dane. To zachowanie jest często monitorowane przez licznik perfmon zwany „Page Life Expectancy” (PLE) :

Definicja PLE to oczekiwany czas w sekundach, przez jaki strona pliku danych wczytana do puli buforów (pamięć podręczna stron plików danych) pozostanie w pamięci przed wypchnięciem z pamięci, aby zrobić miejsce na inne dane strona pliku. Innym sposobem myślenia o PLE jest natychmiastowy pomiar nacisku na pulę buforów, aby zwolnić miejsce na strony odczytywane z dysku. Dla obu tych definicji wyższa liczba jest lepsza.

Podczas wykonywania zapytania SQL Server może używać tempdb do niektórych operacji. Zwykle dzieje się tak, jeśli szacunki są złe, ale niska dostępna pamięć może wpłynąć na to zachowanie.

Niektóre operacje, które mogą „rozlać” się w ten sposób na tempdb, to mieszanie wierszy (dla złączeń lub agregacji itp.), Sortowanie wierszy w pamięci i buforowanie wierszy podczas wykonywania równoległego zapytania.

Zapytania użytkowników mogą również jawnie używać tempdb (z globalnymi lub lokalnymi tabelami tymczasowymi) i domyślnie używać tempdb (z migawką lub odczytać poziomy izolacji zatwierdzonych migawek).

Żadna z tych sytuacji nie wydaje się pasować do cytowanego przez ciebie stwierdzenia.

gdy nie ma wystarczającej ilości pamięci fizycznej, system operacyjny może użyć PLIKU STRONY i przenieść do niego dane z pamięci fizycznej

Z pewnością może się tak zdarzyć i jest w większości poza kontrolą SQL Server. Istnieje pokrętło, które można obrócić, aby zapobiec niektórym typom stronicowania na poziomie systemu operacyjnego, a mianowicie włączyć „Blokowanie stron w pamięci” (LPIM) :

Ta zasada systemu Windows określa, które konta mogą wykorzystywać proces do przechowywania danych w pamięci fizycznej, uniemożliwiając systemowi stronicowanie danych do pamięci wirtualnej na dysku.

Czego możemy więc uniknąć stronicowania na dysk?

W wersjach wcześniejszych niż SQL Server 2012 strony przydzielone przez komponent o nazwie „Alokator pojedynczej strony” były zablokowane w pamięci (nie można było stronicować). Obejmowało to pulę buforów (strony bazy danych), pamięć podręczną procedur i niektóre inne obszary pamięci.

Zobacz temat Zabawa z zablokowanymi stronami, AWE, Menedżerem zadań i zestawem roboczym…, aby uzyskać szczegółowe informacje, szczególnie w sekcji „4. Teraz wiem, że SQL Server na x64 może używać„ Blokowanych stron ”, co dokładnie jest zablokowane?” Dodatkowe powiązane lektury można znaleźć tutaj: Świetne debaty SQL Server: Blokowanie stron w pamięci

W SQL Server 2012 i nowszych wersjach nie ma „alokatora pojedynczej strony” (alokatory jedno- i wielostronicowe zostały połączone, według szczegółowego spojrzenia na pamięć - SQL Server 2012/2014 ). Szczegóły tego, co dokładnie można, a czego nie można umieścić na stronach, nie jest szczegółowo udokumentowane w żadnym miejscu, które widziałem. Można użyć kwerendy tak aby zobaczyć, co jest zablokowany

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'

W tym samym artykule MS Support możesz także DBCC MEMORYSTATUSsprawdzić, ile pamięci jest „zablokowane”.

Na marginesie można zauważyć, że zestaw roboczy programu SQL Server jest stronicowany przez system operacyjny w dzienniku błędów. Pojawią się wiadomości, które wyglądają tak:

2019-09-02 10: 19: 27.29 spid11s Znaczna część pamięci procesowej serwera SQL została stronicowana. Może to spowodować pogorszenie wydajności. Czas trwania: 329 sekund. Zestaw roboczy (KB): 68780, zatwierdzony (KB): 244052, wykorzystanie pamięci: 28%.


0

Nowoczesne wersje serwera SQL mają naprawdę małą szansę na całkowite rozłączenie się. SQL Server ładuje .NET Framework do swojej przestrzeni adresowej i używa go podczas normalnej pracy. Jeśli skończy się pamięć fizyczna i plik strony, system Windows spróbuje powiększyć plik strony; jednak nawet jeśli może on powiększać plik strony, nie jest to operacja natychmiastowa, a alokacja pamięci kończy się niepowodzeniem, gdy plik strony rośnie. Wystąpił błąd w asynchronicznym module obsługi we / wy platformy .NET, który przydziela pamięć w odpowiedzi na powiadomienie APC. Jeśli połączenie newnie powiedzie się, zostanie rzuconeOutOfMemoryException. Ten wyjątek jest wychwytywany w natywnym kodzie wewnątrz harmonogramu zadań; jednak asynchroniczne operacje we / wy wydają się nigdy nie kończyć. Wątek finalizatora dla FileStream będzie blokował oczekiwanie na zakończenie operacji we / wy, aby mógł odpiąć bufor, tym samym zawieszając wątek finalizatora na zawsze. Powoduje to, że .NET Framework stopniowo zużywa coraz więcej pamięci, dopóki pamięć nie będzie mogła zostać przydzielona. W tym momencie serwer SQL przestanie odpowiadać, ponieważ winsock nie może już przydzielić buforów, więc nawet połączenie dostępu administratora jest bezużyteczne.

Rzeczywiście trafiłem na całkowite zawieszenie się harmonogramu zadań w aplikacji .NET z powodu braku pamięci. Na szczęście proces w końcu OutOfMemoryExceptionzakończył się z powodu rzucenia jakiegoś wątku, który nie złapał go po kilku awariach, abyśmy mogli dowiedzieć się, co właściwie zawiesiło serwer.

Gdy już wiedziałem, czego szukam, znalezienie błędu w analizie statycznej było łatwe.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.