On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru






 

Новые правила для shared pool в версии 8.1

Стив Адамс

Управление фрагментацией разделяемого пула (shared pool) в Oracle 8.1.

Настройка буфера shared pool в Oracle - один из наиболее сложных видов настройки. К счастью, с нею приходится иметь дело далеко не всем. Большинство администраторов может себе позволить попросту выставить размер shared pool очень большим, так что риск столкнуться в результате этого со снижением производительности для них окажется невелик. Однако если вдруг на сервере в большом количестве выполняются фазы трансляции и исполнения SQL-запросов, к выставлению размера shared pool требуется отнестись с большой осторожностью: неудачный размер может привести к увеличению числа конкурирующих заявок на использование защелок (фиксаторов), которые регулируют работу библиотечного буфера и shared pool (library cache latches и shared pool latches).

Основная причина возникновения конкуренции за использование зашелок shared pool кроется в фрагментации свободной памяти. Если свободная память превращается в большой набор небольших кусков, то процесс, подыскивающий себе кусок по размеру, будет держать защелку shared pool долгое время. Степень фрагментированности свободной памяти очень легко посмотреть с помощью сценария shared_pool_free_lists фирмы Ixora. Для сокращения фрагментации ключевым является закрепление в библиотечном буфере попавших туда объектов, а также выставление размера shared pool в меру необходимого - и не более того.

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

Сращивание 'с передним'

Если кусок памяти освобождается, и следующий кусок тоже свободен, то Oracle соединит эти два свободных куска в один. Это называется сращиванием 'с передним'. Такой метод эффективен, так как для проверки занятости системе достаточно заглянуть в 16-байтовый заголовок следующего куска. В том же заголовке хранятся указатели на предыдущий и следующий куски в свободном списке. Их наличие позволяет просто удалить в случае надобности этот кусок из списка свободных и ликвидировать возникшую в списке 'дыру'.

По нашим наблюдениям в версии 8.1 Oracle при освобождении ранее занятого куска сращивает его теперь не с одним, как раньше, а со всеми следующими сразу после него смежными свободными кусками. Это приводит к тому, что 'сбрасывать' вручную состояние shared pool командой flush для сращивания свободных кусков в один теперь нужно реже, чем это требовалось раньше. Соответственно, в таком ручном 'сбросе' пользы теперь будет значительно меньше, особенно когда shared pool сформирована без запаса.

Резерв постоянной памяти

Резерв постоянной памяти - это участок свободной памяти, оставляемый при старте системы в shared pool 'про запас'. Так, если параметр shared_pool_size выставлен в 10,000,000 байт и структуры постоянной (permanent) памяти требуют с самого старта 1,000,000 байт плюс к этому дополнительно, то общий размер shared pool будет 11,000,000 байт. В момент запуска системы, тем не менее, для использования будет выдано из shared pool 5,500,000 байт, а остальные 4,500,000 байт свободной памяти будет зарезервировано в виде куска постоянной основной памяти в 'одну кассу' с 1,000,000 байт постоянной памяти. Резерв постоянной памяти освобождается по мере необходимости - всякий раз по 50% от имеющегося запаса.

Освобождаемые в процессе работы куски из резерва постоянной памяти оказываются фрагментированы намного менее своих 'собратьев', доступных для использования с самого начала. Однако в версии 7 выделение памяти из резерва осуществлялось неоправданно долго, так что нередко предпочтительнее оказывалось освободить давно неиспользуемые куски в соответствии с LRU-списком. В версии 8 освобождению 'старых' кусков (по LRU-списку) всегда предшествует попытка найти место в резерве постоянной памяти.

Резервный пул

Резервный пул (а точнее - резервный список внутри shared pool) не следует путать с резервом постоянной памяти. Резервный пул имеет постоянное предназначение выдавать большие куски памяти, в то время как резерв постоянной памяти выступает в качестве временного резерва, на время старта системы, для предотвращения избыточной фрагментации. Тем не менее, размеры этих двух областей памяти связаны друг с другом. Размер резервного пула не может быть больше 20% shared pool; его наличие приводит к тому, что резерв постоянной памяти не будет освобождаться чересчур быстро и фрагментация уменьшится.

Однако начиная с версии 8.0, когда использование резервного пула стало обязательным, он нередко в процессе работы оставался нетронутым. Этому способствовали два обстоятельства. Во-первых, в последних версиях Oracle просто берет большие куски из shared pool, если находит в свободном списке кусок достаточно большого размера, не прибегая к просмотру LRU-списка в поисках кандидатов на освобождение памяти в компьютере. А во-вторых, Oracle теперь очень редко нуждается в кусках памяти, больше 5000 байт (значение параметра _shared_pool_reserved_min_alloc по умолчанию). Минимально допустимое значение для этого параметра доведено до 4000 байт, и использование этого значения позволяет вам более успешно справляться с фрагментацией памяти, уменьшая риск появления ошибки ORA-4031 и не требуя обращения к LRU-списку при необходимости размещения кусков в диапазоне от 4000 до 5000 байт.

Скрипт shared_pool_free_lists.sql

-------------------------------------------------------------------------------

--

-- Script: shared_pool_free_lists.sql

-- Purpose: to check the length of the shared pool free lists

-- For: 8.1.6 to 8.1.7

--

-- Copyright: (c) Ixora Pty Ltd

-- Author: Steve Adams

--

-------------------------------------------------------------------------------

@save_sqlplus_settings

select

decode(

sign(ksmchsiz - 812),

-1, (ksmchsiz - 16) / 4,

decode(

sign(ksmchsiz - 4012),

-1, trunc((ksmchsiz + 11924) / 64),

decode(

sign(ksmchsiz - 65548),

-1, trunc(1/log(ksmchsiz - 11, 2)) + 238,

254

)

)

) bucket,

sum(ksmchsiz) free_space,

count(*) free_chunks,

trunc(avg(ksmchsiz)) average_size,

max(ksmchsiz) biggest

from

sys.x_$ksmsp

where

inst_id = userenv('Instance') and

ksmchcls = 'free'

group by

decode(

sign(ksmchsiz - 812),

-1, (ksmchsiz - 16) / 4,

decode(

sign(ksmchsiz - 4012),

-1, trunc((ksmchsiz + 11924) / 64),

decode(

sign(ksmchsiz - 65548),

-1, trunc(1/log(ksmchsiz - 11, 2)) + 238,

254

)

)

)

/

@restore_sqlplus_settings

 

Вид выходного листинга

SQL> @shared_pool_free_lists

BUCKET FREE_SPACE FREE_CHUNKS AVERAGE_SIZE BIGGEST

---------- ---------- ----------- ------------ ----------

0 166344 3872 42 72

1 32208 374 86 96

4 928 1 928 928

6 11784 4 2946 3328

 




Литература по Oracle