Что происходит, когда не хватает доступной физической памяти для SQL Server?

16

При поиске я нашел противоречивую информацию.

Некоторые сайты заявляют, что, когда для данных не остается физической памяти, SQL Server перемещает уже существующие данные в TEMPDB (см. SQL Server: Демистификация TempDb и рекомендации ).

Но другие сайты утверждают, что, когда физической памяти недостаточно, операционная система может использовать файл PAGE FILE и перемещать в него данные из физической памяти (см. Файл подкачки для SQL Server ).

Интересно, куда SQL Server записывает данные, когда ему не хватает физической памяти? В tempdb или в файл OS Page? Или может они оба?

RaufDBA
источник

Ответы:

28

если для данных не осталось физической памяти, SQL Server перемещает уже существующие данные в TEMPDB

Статья, на которую вы ссылаетесь, в лучшем случае вводит в заблуждение, а в некоторых местах неверна. Я думаю, что автор пытался чрезмерно упростить некоторые сложные вещи, и при этом зашел слишком далеко.

SQL Server таким образом не перемещает данные из памяти (буферного пула) в базу данных tempdb. Он использует стратегию кеширования с «наименьшим количеством использовавшихся в последнее время» (в общем случае), поэтому, если существует нехватка памяти и новые данные должны быть извлечены в память, SQL Server выбрасывает данные LRU из пула буферов для размещения новых данных. Такое поведение часто отслеживается счетчиком perfmon, который называется «Ожидаемая продолжительность жизни страницы» (PLE) :

Определение PLE - это ожидаемое время в секундах, в течение которого страница файла данных, считанная в пул буферов (кэш-память страниц данных в памяти), останется в памяти перед тем, как ее вытолкнут из памяти, чтобы освободить место для других данных. Страница файла. Другой способ думать о PLE - это мгновенная мера давления на буферный пул, чтобы освободить место для страниц, читаемых с диска. Для обоих этих определений большее число лучше.

Во время выполнения запроса SQL Server может использовать базу данных tempdb для определенных операций. Обычно это делается, если оценки плохие, но нехватка доступной памяти может влиять на это поведение.

Некоторые из операций, которые могут таким образом «пролить» на базу данных tempdb, - это хэширование строк (для объединений или агрегатов и т. Д.), Сортировка строк в памяти и буферизация строк при выполнении параллельного запроса.

Пользовательские запросы также могут явно использовать базу данных tempdb (с глобальными или локальными временными таблицами) и неявно использовать базу данных tempdb (с уровнями изоляции моментального снимка или чтения зафиксированных моментальных снимков).

Похоже, что ни одна из этих ситуаций не соответствует приведенному вами утверждению.

когда физической памяти недостаточно, операционная система может использовать файл PAGE FILE и перемещать в него данные из физической памяти.

Это, безусловно, может произойти, и по большей части находится вне контроля SQL Server. Есть кнопка, которую можно повернуть, чтобы попытаться предотвратить некоторые типы подкачки на уровне ОС, а именно включить «Блокировку страниц в памяти» (LPIM) :

Эта политика Windows определяет, какие учетные записи могут использовать процесс для хранения данных в физической памяти, предотвращая подкачку данных системой в виртуальную память на диске.

Так что же мы можем предотвратить подкачку на диск?

До SQL Server 2012 страницы, которые были выделены с помощью компонента, называемого «одностраничный распределитель страниц», были заблокированы в памяти (не могли быть выгружены страницы). Это включало пул буферов (страницы базы данных), кеш процедур и некоторые другие области памяти.

Подробнее см. В разделе Fun with Locked Pages, AWE, Task Manager и рабочем наборе… особенно в разделе «4. Теперь я знаю, что SQL Server на x64 может использовать« Locked Pages », что именно заблокировано?» Дополнительное связанное чтение можно найти здесь: Великие дебаты по SQL Server: блокировка страниц в памяти

В SQL Server 2012 и более поздних версиях «одностраничный распределитель» отсутствует (одностраничный и многостраничный распределители были объединены в соответствии с подробным обзором памяти - SQL Server 2012/2014 ). Детали того, что именно может и не может быть разбито на страницы, подробно не документированы нигде, что я видел. Вы можете использовать запрос , как это , чтобы увидеть , что будет закрыт

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'

В той же статье службы поддержки MS вы также DBCC MEMORYSTATUSможете узнать, сколько памяти «заблокировано».

В качестве примечания вы можете увидеть свидетельство того, что операционный набор SQL Server разбит на страницы ОС в журнале ошибок. Будут сообщения, которые выглядят так:

2019-09-02 10: 19: 27.29 spid11s Значительная часть памяти процесса сервера sql была выгружена. Это может привести к снижению производительности. Продолжительность: 329 секунд. Рабочий набор (КБ): 68780, зафиксированный (КБ): 244052, использование памяти: 28%.

Джош Дарнелл
источник
0

Современные версии SQL-сервера имеют очень маленький шанс повесить трубку. SQL Server загружает .NET Framework в свое адресное пространство и использует его при нормальной работе. Если физическая память и файл подкачки исчерпаны, Windows попытается увеличить файл подкачки; однако даже если он может увеличить файл подкачки, это не мгновенная операция, и выделение памяти не происходит, когда файл подкачки увеличивается. В обработчике асинхронного ввода-вывода .NET есть ошибка, из-за которой он выделяет память в ответ на уведомление APC. Если вызов newне удастся, он броситOutOfMemoryException, Это исключение перехватывается в собственном коде внутри планировщика задач; однако асинхронный ввод-вывод никогда не завершится. Поток финализатора для FileStream будет блокировать ожидание завершения ввода-вывода, чтобы он мог открепить буфер, тем самым навсегда повесив поток финализатора. Это приводит к тому, что .NET Framework постепенно использует все больше и больше памяти до тех пор, пока не будет выделено больше памяти, и в этот момент SQL-сервер перестанет отвечать на запросы, поскольку winsock не сможет больше выделять буферы, поэтому даже подключение для доступа администратора бесполезно.

На самом деле я столкнулся с полным зависанием планировщика задач в приложении .NET из-за нехватки памяти. К счастью, этот процесс, в конце концов, OutOfMemoryExceptionпрекратился из-за того, что после нескольких сбоев возник поток, который не перехватил его, чтобы мы могли выяснить, что на самом деле зависало на сервере.

Как только я понял, что искал, найти ошибку в статическом анализе стало легко.

Джошуа
источник