Użyta pamięć nie została zwolniona po eksporcie SQL BULK Insert / BCP

10

Utworzyłem bardzo podstawową tabelę SQL w następujący sposób

CREATE TABLE [dbo].[TickData](
[Date] [varchar](12) NULL,
[Time] [varchar](12) NOT NULL,
[Symbol] [varchar](12) NOT NULL,
[Side] [varchar](2) NOT NULL,
[Depth] [varchar](2) NOT NULL,
[Quote] [varchar](12) NOT NULL,
[Size] [varchar](18) NOT NULL
    ) ON [PRIMARY]

Następnie wykonałem 3 Gig Bulk Insert

    BULK
    INSERT TickData
    FROM 
    'C:\SUMO.csv'
    GO

Następnie użycie pamięci RAM dla serwera SQL poszło w górę Skyrocking, pochłaniając ~ 30Go pamięci RAM:

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Wolę myśleć, że jest to zachowanie nienormalne i że można to zrobić, aby tego uniknąć.

EDYCJA:
Ok, wydaje się, że jest to zachowanie domyślne. Słusznie.
Jednak dlaczego nie jest pamięć zwolniona długo po Bulk Insert jest zakończona?

Kilka dodatkowych uwag:
Jeśli chodzi o komentarze dotyczące zwalniania pamięci przez serwer SQL, gdy system operacyjny „nakazuje mu to”, moje praktyczne doświadczenia z 24-rdzeniowym serwerem Xeon 32 Gb dowodzą, że jest to niedokładne: gdy skończy się żarłoczny wyciąg BCP Mam pulę wystąpień .Net mojej aplikacji do przetwarzania danych, które muszą przetwarzać wyodrębnione dane, i pozostawiają duszenie / walkę o współdzielenie pozostałej pamięci, aby spróbować wykonać swoje zadania, co zajmuje faaaaar dłużej niż po włączeniu SQL Server wyłączone i pamięć jest dostępna dla wszystkich aplikacji do udostępniania. Muszę zatrzymać SQL Server Agent, aby wszystko poszło gładko i zapobiec awariom aplikacji w przypadku Articiallt, które spowodowało wyjątek OutOfMemmroy. Jeśli chodzi o sztuczne ograniczenie / ograniczenie pamięci brutalnej, jeśli dostępna jest wolna pamięć, dlaczego tego nie użyć? Idealnie byłoby raczej dynamicznie przystosować się do tego, co jest dostępne, niż po prostu ograniczać się „losowo”. Ale myślę, że jest to zgodne z projektem, więc sprawa została zamknięta w tej ostatniej kwestii.

Mehdi LAMRANI
źródło
6
Dlaczego SQL Server powinien zwalniać pamięć? Jeśli potrzebowała pamięci, aby wykonać tę operację raz, będzie jej potrzebować ponownie. Jeśli SQL Server zwolni pamięć, do czego jej użyjesz? Dlaczego pamięć musi być wolna? Jeśli użyjesz pamięci do czegoś innego, to ta wkładka zbiorcza uruchomi się ponownie, co powinno się stać?
Aaron Bertrand
Jedynym działaniem, jakie można podjąć, aby tego uniknąć, jest ustawienie maksymalnego rozmiaru pamięci. Aby „odzyskać” pamięć, możesz ponownie uruchomić usługę SQL Server. Oczywiście spowoduje to zwolnienie pamięci, a kiedy usługa uruchomi się ponownie, przydzieli pamięć normalnie.
TMN
Posprzątałem ostatnią edycję. Jeśli chcesz spierać się o dyskusję na temat zalet lub problemów związanych z kodowaniem SQL Server (lub dowolnego innego silnika DB), znajdź lepsze miejsce do zrobienia tego. Na pierwotne pytanie udzielono odpowiedzi, pozornie poprawnej i wystarczającej. Jeśli to Q nadal się skrada, może zostać zablokowane.
JNK
Nie ma nic złego w chęci poznania odpowiedzi i omówienia metodologii, po prostu nie tutaj na stronie pytań i odpowiedzi. Na pewno możesz prowadzić tę dyskusję na czacie lub na forum, ale Stack Exchange jest nieco bardziej uporządkowany, a pytania dyskusyjne zostaną szybko zamknięte.
JNK
3
Ponadto, jako nie-moderator, zastanawiam się, dlaczego uruchamiasz rzeczy inne niż SQL na swoim serwerze? Pole powinno być zarezerwowane TYLKO dla SQL Server, to jest jak DBA 101. Silnik nie został zaprojektowany dla środowiska zasobów współdzielonych.
JNK

Odpowiedzi:

12

SQL Server przydziela jak najwięcej pamięci do swojej puli buforów. Bazy danych działają najlepiej z dużą ilością bufora. Jeśli chcesz zmienić zachowanie, możesz ustawić ustawienie „maksymalna pamięć serwera” . Kilka dobrych lektur na ten temat jest tutaj.

Matt Whitfield
źródło
1
Jeśli chodzi o twoją edycję, komentarz Aarona jest dobry. Powodem jest to, że serwer bazy danych nie ma sensu zwalnianie pamięci. SQL Server zareaguje na presję pamięci i zwolni pamięć, jeśli naprawdę musi, ale tak naprawdę nie powinno to być konieczne.
Matt Whitfield,
@MikaJacobi Przepraszamy, ale Twoja druga edycja jest po prostu błędna. Z punktu widzenia programisty rozumiem twój punkt widzenia, ale istnieje różnica między budowaniem grupy współistniejących aplikacji a usługą serwerową, która naprawdę powinna być jedyną usługą zajmującą pamięć. Jeśli chcesz, aby SQL Server zachowywał się jak „normalna” aplikacja, ustaw maksymalną pamięć i odejdź. Twoje pytanie brzmiało: dlaczego to działa w ten sposób i na które odpowiedziano. Jeśli twoje pytanie brzmi „cóż, nie podoba mi się, że tak działa” - przepraszam, ale to już nie jest pytanie.
Aaron Bertrand
Słusznie. Moim punktem widzenia jest to, że powinna istnieć opcja włączenia lub wyłączenia tego, a założenie, że SQL Server jest jedyną aplikacją na serwerze, jest naprawdę obelżywe (może być prawdziwe dla dużych firm z dużymi sieciami, ale to nie jedyne możliwa ani najczęstsza konfiguracja)
Mehdi LAMRANI
Nadal nie rozumiem, dlaczego potrzebujesz programu SQL Server, aby zwolnić pamięć. Jeśli inne aplikacje będą go potrzebować, zabiorą go z powrotem z SQL Server, a SQL Server będzie zgodny. Dopóki inne aplikacje tego nie potrzebują, jaki jest cel zwolnienia pamięci?
Aaron Bertrand
1
@AaronBertrand Ok, mogę się mylić, ale jak stwierdzono w mojej ostatniej edycji, nie byłem tego świadkiem: Pamięć nie została zwolniona, gdy inna aplikacja jej nie potrzebowała, powodując awarie pamięci (stąd moje niezadowolenie ...) W każdym razie zamknij temat, myślę, że nie ma prawdziwej potrzeby dyskutować więcej niż to.
Mehdi LAMRANI
7

Jeśli naprawdę chcesz, aby system operacyjny zabrał pamięć z SQL Server, weź duży plik o wielkości 20 GB i skopiuj go przez sieć. SQL Server zwolni pamięć zgodnie z wymaganiami systemu operacyjnego. Ale w tym czasie oglądałbym różne liczniki wydajności i sprawdzałbym, jak zmienia się wydajność twojego WSTAWKI LUZOWEJ, jeśli uruchomisz ją ponownie podczas działania kopii lub bezpośrednio po niej.

Jeśli chcesz to zrobić ręcznie, powinieneś ustawić dolny limit maksymalnego ustawienia pamięci serwera SQL Server i zrestartować usługę. Teraz SQL Server nie będzie używać 28 GB, nawet jeśli będzie go potrzebować. Ale to wydaje się sztucznie ograniczać SQL Server.

Wydaje się, że oczekujesz bardziej elastycznego zachowania, w którym możesz mieć przez pewien czas wolną pamięć. W jakim celu? Czy to jest jak zmniejszanie pliku bazy danych w celu zwolnienia miejsca na dysku, którego nie można użyć do innych celów, ponieważ plik bazy danych znów się powiększy?

To zabawne, jeśli wpiszesz w wyszukiwarce Google hasło „dlaczego SQL Server”, najczęstszym automatycznym uzupełnianiem jest „zwolnij pamięć”.

Aaron Bertrand
źródło
„Wydaje się, że oczekujesz bardziej elastycznego zachowania”. Dokładnie. Chcę, aby serwer SQL wykorzystywał całą dostępną pamięć, gdy jest ona dostępna, ale kiedy te ciężkie chwile się skończyły, powróciłem do stanu „uśpienia” i pozostawiłem innym aplikacjom wymagającym pamięci, aby wykonały swoją pracę wygodnie (możesz spojrzeć na mój nowa ostatnia edycja w tym punkcie)
Mehdi LAMRANI
Aby zobaczyć konkretny przypadek ilustrujący, dlaczego muszę to zrobić, możesz spojrzeć na @ mój ostatni komentarz do JNK na końcu pytania
Mehdi LAMRANI
4

Jest to niestety zgodne z projektem, zapoznaj się z tym postem. Jednak w tym poście zawiera instrukcje dotyczące kontrolowania tego.

/server/251832/sql-server-bulk-insert-physical-memory-issue

Edycja alokacji pamięci

Brak pamięci freed, ponieważ alokuje pamięć bardzo podobnie jak aplikacja .NET. Ponieważ przydział pamięci jest kosztowny, zostanie on zachowany, chyba że system operacyjny tego zażąda. Ale nie obawiaj się, jeśli system operacyjny chce pamięci, dostanie ją, podobnie jak w aplikacji .NET.

Mike Perrenoud
źródło
@MikaJacobi Pewnie, nie ma problemu. Należy zwrócić uwagę na jeszcze jedną rzecz: SQL Server przejmie również wszystkie rdzenie, dlatego należy ograniczyć liczbę dostępnych rdzeni. Widziałem, jak SQL Server faktycznie niszczy system operacyjny, na którym działa, i musiałem ponownie uruchomić SQL Server w centrum danych.
Dobrze wiedzieć. Mam 24 rdzenie, więc na razie jest ok. Ale dlaczego pamięć nie jest zwalniana po zakończeniu wkładki luzem?
Tak długo, jak wkładka zbiorcza jest ukończona, jeśli system operacyjny potrzebuje pamięci, zostanie jej przydzielony, ale przydziela pamięć podobnie jak aplikacja .NET, więc jeśli potrzebuje i nikt inny nie może uzyskać do niej dostępu szybciej.
Moje przeżarte doświadczenia są temu sprzeczne (zobacz ostatnią edycję).
Mehdi LAMRANI