Управление оперативной памятью
ОГЛАВЛЕНИЕ
Помимо этого ранние версии SQL Server не только требовали выделения фиксированного объема оперативной памяти для всего SQL Server, но также распределяли выделенный объем памяти по секциям для выполнения определенных целей. Одна из таких секций, процедурный кэш, предназначалась только для хранения планов исполнения запросов и хранимых процедур. Размер процедурного кэша фиксировался при старте службы SQL Server и, подобно общему объему выделяемой памяти, размер этого кэша нельзя было изменить при перезапуске SQL Server.
Начиная с версии SQL Server 7.0, вся картина управления памятью коренным образом изменилась. У системных администраторов не только появилась возможность динамически изменять общий объем выделенной для SQL Server памяти, но и перераспределять в случае необходимости память внутри SQL Server между различными системными ресурсами. Если SQL Server требуется больше памяти для планов исполнения запросов, можно освободить несколько страниц, содержащих данные, и заполнить их планами исполнения запросов. Или же наоборот, если требуется больше памяти для данных, считываемых с жесткого диска, то можно удалить из оперативной памяти планы редко исполняемых запросов.
Поскольку я знаю, что в SQL Server реализована стратегия динамического использования оперативной памяти, меня очень удивил вопрос о работе процедурного кэша, который мне задал слушатель на одном из семинаров. Он где-то читал о новом переключателе, который можно использовать при запуске SQL Server 7.0, чтобы ограничить объем используемой процедурным кэшем оперативной памяти. Хотя я ничего не знала об этом переключателе, я верила, что слушатель не выдумал эту возможность. Однако в SQL Server 7.0 нет ничего, что называлось бы процедурным кэшем, поэтому после семинара я занялась изучением ситуации. В файле readme_txt, который сопровождает пакет с исправлениями Service Pack 2 (SP2) для SQL Server 7.0, я обнаружила то, о чем говорил мой коллега. Но прежде чем я расскажу об этом переключателе, обратимся к основам управления оперативной памятью в SQL Server 2000 и SQL Server 7.0.
Адресное пространство SQL Server
В любой операционной системе производства корпорации Microsoft общий объем виртуальной памяти, доступный некоторому приложению, называется адресным пространством этого приложения. Для SQL Server максимальный размер виртуальной памяти составляет 2 Гбайт, если только не используется специальный режим. В файле boot.ini операционной системы Windows NT Enterprise Edition или Windows 2000 Advanced Server можно воспользоваться переключателем /3GB для увеличения размера адресного пространства до 3 Гбайт.
У каждого экземпляра SQL Server имеется адресное пространство, состоящее из двух основных компонентов. Один основной компонент представляет собой буферный пул, который выделяет оперативную память порциями (или буферами) по 8 Кбайт. Как SQL Server 2000, так и SQL Server 7.0 используют это пространство для хранения страниц данных и индексов, которые SQL Server считывает с жесткого диска; кэша журнала транзакций; планов исполнения запросов и хранимых процедур; системных конструкций, таких как таблица блокировок; а также для информации пользовательских процессов. Кое-что из перечисленного можно увидеть при помощи системных хранимых процедур sp_who и sp_who2. Обычно адресное пространство этой области занимает почти весь объем оперативной памяти машины. Однако можно ограничить количество памяти, которое SQL Server будет в состоянии использовать для буферов кэширования, если при создании конфигурации SQL Server указать параметр max server memory , то есть максимальный размер оперативной памяти, доступный для SQL Server.
Второй компонент адресного пространства SQL Server представляет собой область памяти, которую я обычно называю небуферным пулом. Эта область оперативной памяти зарезервирована, прежде всего, для компонентов исполняемого кода или для компонентов, требующих выделения больших объемов оперативной памяти порциями, превосходящими 8 Кбайт. К числу таких компонентов относятся: исполняемые файлы и динамические библиотеки DLL, которые используют в работе Open Data Services и серверные сетевые библиотеки Network-Libraries; библиотеки DLL поставщика OLE DB для сервера, на котором функционирует SQL Server; а также расширенные хранимые процедуры, используемые в динамических библиотеках DLL и системных хранимых процедурах OLE Automation для создания экземпляров объектов OLE Automation. Эта область памяти может также содержать планы исполнения запросов и хранимых процедур, которым требуются большие объемы памяти.
Когда служба SQL Server стартует, операционная система загружает в оперативную память исполняемые модули SQL Server и те статические библиотеки DLL, которые требуются операционной системе. После этого резервируется секция адресного пространства для использования в качестве небуферного пула. По умолчанию SQL Server резервирует 128 Mбайт общего адресного пространства плюс необходимый размер памяти для стеков всех потоков. Этот размер вычисляется на основании указываемого в конфигурации параметра max worker threads (максимальное количество рабочих потоков). Для одного потока резервируется примерно 0,5 Mбайт памяти.
Буферный пул забирает все оставшееся адресное пространство. В течение всего времени работы SQL Server это пространство будет доступно исключительно буферному пулу (и связанным с ним объектам памяти, которые также используют страницы размером по 8 Кбайт и поэтому могут брать память из буферного пула).
В файле readme_txt, который сопровождает пакет SP2, обсуждается применение для SQL Server 7.0 стартового переключателя /g memory_to_reserve, который можно использовать для изменения размера области оперативной памяти, выделяемого в качестве резерва для небуферного компонента адресного пространства. Вот что там говорится:
[Этот переключатель] задает целое число мегабайтов оперативной памяти, которые SQL Server оставит доступными для распределения памяти внутри процесса SQL Server, однако за пределами пула оперативной памяти SQL Server. Пул оперативной памяти представляет собой область памяти, которую SQL Server использует для загрузки в нее специфических элементов. К ним относятся файлы библиотек .dll для расширенных хранимых процедур; поставщики OLE DB, к которым обращаются распределенные запросы, а также объекты OLE Automation, на которые имеются ссылки в предложениях Transact-SQL.
Мне показалось, что это описание, содержащееся в файле readme_txt, может внести некоторую путаницу из-за неоднозначной трактовки терминов. Наибольшие сомнения вызывает использование термина пул оперативной памяти, memory pool. Специалисты, работающие в команде разработчиков SQL Server в корпорации Microsoft, сказали мне, что при общении между собой они никогда не употребляют термин пул оперативной памяти. Поэтому я буду продолжать использовать термины буферный пул и небуферный пул.
Когда следует пользоваться этим переключателем?
Если имеется большой объем оперативной памяти, и процесс SQL Server исчерпал все выделенное ему виртуальное адресное пространство, может возникнуть необходимость изменить объем памяти, зарезервированной для небуферного пула. Попробуйте воспользоваться переключателем /g, если в журнале ошибок SQL Server начинает регулярно появляться следующее сообщение:
Warning: Clearing procedure cache to free contiguous memory.
Предупреждение: очистка процедурного кэша для освобождения смежной области оперативной памяти.
Это сообщение порождается объектами оперативной памяти, такими как планы исполнения процедур и запросов, которые обычно заимствуют оперативную память из буферного пула. Когда этим объектам приходится распределять память порциями, размер которых превышает 8 Кбайт, они вынуждены обращаться за оперативной памятью к области небуферного пула. Если же в области небуферного пула размер непрерывной памяти оказывается недостаточным, SQL Server начинает удалять из оперативной памяти хранящиеся там планы исполнения процедур. Тем самым SQL Server пытается найти необходимый объем памяти, прежде чем повторять всю операцию заново.
Однако обратите внимание на короткое предупреждение, приведенное в файле readme пакета SP2. Оно гласит: "incorrect use of this option (/g) can lead to conditions under which SQL Server may not start or may encounter run-time errors". То есть в результате некорректного применения этого режима может случиться так, что SQL Server будет не в состоянии стартовать, или будут возникать ошибки в процессе работы. Поэтому необходимо убедиться в том, что остается достаточный объем оперативной памяти для внутренних структур SQL Server и минимальное количество страниц памяти для данных и планов исполнения запросов.
В некоторых случаях переключатель /g можно использовать для снижения избыточного объема зарезервированной памяти. Уменьшение размера зарезервированного пространства оперативной памяти позволит увеличить объем памяти, доступный для размещения страниц данных и индексов. А это, в свою очередь, приведет к росту производительности приложений, интенсивно использующих оперативную память.
Мои рекомендации
Я настоятельно рекомендую читателям провести тщательное тестирование переключателя /g и не прибегать к его использованию до тех пор, пока в этом действительно не возникнет необходимость. Хотя файл readme, на который я ссылаюсь в настоящей статье, а также описание переключателя /g относятся к версии SQL Server 7.0, тот же самый переключатель существует и в версии SQL Server 2000. Помните, что в SQL Server 2000 по умолчанию объем оперативной памяти вне буферного пула равен 256 Мбайт, в то время как в SQL Server 7.0 он составляет 128 Кбайт. Кроме того, этот переключатель выйдет из употребления, когда появится 64-разрядная версия SQL Server. Ведь тогда адресное пространство любого приложения выйдет далеко за пределы, которые сегодня ограничивают его размер двумя или тремя мегабайтами.
Тем, кто не читает файлы readme, полагая, что они предназначены исключительно для начинающих, я советую пересмотреть свою точку зрения. Многие, если не все, файлы readme, сопровождающие пакеты исправлений и исходные продукты, содержат важные сведения о возможностях и поведении программ. К примеру, в один из пакетов с исправлениями для SQL Server 6.5 разработчики корпорации Microsoft включили несколько новых возможностей создания конфигурации системы. А поскольку ни печатная, ни сетевая документация не обновлялись, единственный способ узнать об этих возможностях - прочитать файл readme.txt.
Кэлен Дилани (Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript., www.InsideSQLServer.com) имеет сертификаты MCT и MCSE, работает независимым консультантом и преподавателем на северо-западе тихоокеанского побережья США. Начала работать с SQL Server еще в 1987 году. Кэлен написала книгу "Inside SQL Server 7.0", выпущенную издательством Microsoft Press; она также является соавтором книг "SQL Server 6.5 Unleashed" и "Teach yourself SQL Server in 21 days", изданных в Sams Publishing.