Назад | Перейти на главную страницу

Как найти основную причину нехватки памяти на сервере SQL 2008?

Один из серверов, на которых я отслеживал производительность, начал выдавать следующие предупреждения от детектора исчерпания ресурсов:

Windows успешно диагностировала нехватку виртуальной памяти. Следующие программы потребляли больше всего виртуальной памяти: sqlservr.exe (1560) потреблял 14960812032 байта, ReportingServicesService.exe (1936) потреблял 506359808 байтов, а w3wp.exe (7376) потреблял 273764352 байта.

SystemCommitLimit 38068215808 SystemCommitCharge 37800669184 ProcessCommitCharge 16727490560 PagedPoolUsage 359088128 PhysicalMemorySize 17098584064 PhysicalMemoryUsage 16881131520 NonPagedPoolUsage 221425664 Процессы 48

Это сервер Windows Server 2008, работающий под управлением MSSQL 2008 R2, имеющий 16 ГБ ОЗУ и 24 процессора. Он запускает SQL и веб-службу, которая обращается к SQL для данных.

Цифры, которые я включил в цитату, взяты из раздела подробностей программы просмотра событий. Мне не удалось определить основную причину. Я уже знаю, что SQL требует много памяти для работы, и в то время он использовал много памяти, но у меня также было установлено ограничение на 14000 МБ.

SQL начал получать ошибку нехватки памяти в дополнение к предупреждениям детектора исчерпания ресурсов.

Каким будет лучший подход к поиску первопричины этого? Я не видел в журналах ничего необычного. После нескольких часов повторения этой ошибки снова и снова память, наконец, закончилась, и службы начали отказывать, пока служба не была перезапущена.

Разве SQL не достаточно умен, чтобы освободить часть своей памяти, когда есть давление? Файл подкачки (виртуальная память) составлял 20 ГБ, а SQL использовал только 16 ГБ физической памяти. Что заполняло остальную виртуальную память? Действительно ли SQL использовал весь этот файл подкачки?

Стоит ли искать утечку памяти? Рост файла журнала?
Файл .mdf, который используется чаще всего на сервере, увеличивается примерно на 100 МБ каждый день. Файл журнала увеличивался на 3 ГБ за раз, а сейчас составляет 40 ГБ.

Обычно при нехватке памяти мы никогда не доходили до того момента, когда сервер просто вылетает. Обычно он просто идет мучительно медленно, пока давление не исчезнет.

Есть ли способ эффективно предотвратить возникновение этой проблемы?

Возможно, вам потребуется увеличить размер файла подкачки, чтобы иметь возможность обрабатывать периодические всплески в размере фиксации памяти. У нас часто возникает эта проблема в вычислениях Azure, где для файла подкачки по умолчанию установлено слишком низкое значение для приложений, интенсивно использующих память.

Вы можете прочитать больше здесь: http://mvolo.com/low-pagefile-can-cause-503-service-unavailable-on-azure-web-roles/

Это не решит проблему, если вашему экземпляру SQL требуется намного больше памяти, чем у вас есть, но это может помочь лучше выдержать временные всплески.

Есть ли способ эффективно предотвратить возникновение этой проблемы?

Бойкий ответ - предложить вам купить больше памяти. Возможно, это не решит вашу проблему, но вряд ли повредит.

SQL Server любит память. SQL Server любит кэшировать вашу базу данных или ее фрагменты в памяти, чтобы к ним можно было обращаться быстрее. Если вы хотите посмотреть, что у вас в памяти прямо сейчас, вы можете получить эту информацию из DMV: http://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/. Один из моих коллег однажды получил рекомендацию поставщика о том, что размер базы данных для БД их продукта никогда не превышает размер памяти сервера. Это непрактично для большинства людей, но если вы пытаетесь обслужить базу данных объемом 10 ТБ с интенсивными запросами и 16 ГБ ОЗУ, это может стать проблемой.

Попробуйте запустить sp_blitz на своем сервере - это хранимая процедура, которая проверяет ваш сервер на наличие проблем. http://www.brentozar.com/blitz/

Также попробуйте perfmon: http://www.brentozar.com/archive/2006/12/dba-101-using-perfmon-for-sql-performance-tuning/

Это должно помочь вам найти причину.

Чтобы правильно диагностировать это, нам нужна дополнительная информация.

SQL-сервер похож на любой другой процесс Windows; его виртуальное адресное пространство может быть намного больше физического ОЗУ. Он может даже быть больше, чем RAM + файлы подкачки, если какая-либо его часть использует файлы с отображением памяти.

Параметр настройки в SQL-сервере - это способ указать ему никогда не использовать больше «x» МБ. Вы должны посмотреть на пиковую плату за фиксацию всех других служб на коробке, вычесть ее из своего физического значения RAM, а затем передать оставшуюся часть SQL Server. Насколько мне известно, ограничение памяти применяется только к РСУБД, а не к зверинцу связанных служб SQL-сервера. Я могу ошибаться здесь.

Значит, по оставшимся процессам нам понадобятся больше цифр. Например, у вас есть рабочий процесс IIS, занимающий 273 МБ; есть только один рабочий процесс? У вас установлено антивирусное программное обеспечение или программное обеспечение для резервного копирования?

Вы можете использовать WSRM, чтобы профилировать происходящее, а затем рассмотреть возможность ограничения памяти. В качестве альтернативы, я бы рекомендовал установить больше оперативной памяти.

Чтобы получить графическое представление о том, где находится ваша память, попробуйте утилиту RAMMap от Microsoft SysInternals.