Oracle DB: Управление памятью

Материал из sysadm
Перейти к навигации Перейти к поиску

Ссылки по теме:

AMM (Automatic Memory Management)

AMM (Automatic Memory Management) - автоматическое управление памятью

Механизм AMM используют статистики, поэтому параметр инициализации STATISTIC_LEVEL должен быть установлен в значение TYPICAL или ALL.

  • memory_target - задает общий размер выделяемой для Oracle DB памяти в рамках которой AMM её автоматически распределяет. Данный параметр можно изменять динамически без остановки инстанции.
  • memory_max_target - задает верхний предел для memory_target. Данный параметр нельзя изменить динамически, необходим перезапуск инстанции.
alter system set memory_target      = 20G scope=both;
alter system set memory_max_target  = 30G scope=spfile;

AMM включается только если задан параметр memory_target.

alter system set memory_target        = 20G scope=spfile;
alter system set sga_target           = 0   scope=spfile;
alter system set pga_aggregate_target = 0   scope=spfile;

-- дополнительно можно задать верхний лимит, если не задан, то считается равным memory_target
alter system set memory_max_target    = 30G scope=spfile;

-- поскольку область применения spfile, то изменения вступят в силу только после перезапуска инстанции

Назначение параметров управления памятью при включенном AMM

  • sga_target - определяет границу ниже которой AMM не может задавать размер SGA
  • pga_aggregate_target - определяет границу ниже которой AMM не может задавать размер PGA
  • sga_max_size - определяет границу выше которой AMM не должен задавать размер SGA

Чтобы рост SGA не приводил к снижению PGA можно зафиксировать размер SGA задав одинаковые значения для sga_target и sga_max_size.

ASMM (Automatic Shared Memory Management)

ASMM (Automatic Shared Memory Management) - автоматическое управление разделяемой памятью

Механизм ASMM используют статистики, поэтому параметр инициализации STATISTICS_LEVEL должен быть установлен в значение TYPICAL или ALL.

ASMM включается заданием параметра sga_target.

ASMM автоматически управляет параметрами

  • SHARED_POOL_SIZE
  • LARGE_POOL_SIZE
  • JAVA_POOL_SIZE
  • DB_CACHE_SIZE
  • STREAMS_POOL_SIZE

Если включен ASMM, то значения данных параметров заданных вручную определяют нижнюю границу выделения памяти для соответствующих областей.

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

  • LOG_BUFFER
  • DB_KEEP_CACHE_SIZE
  • DB_RECYCLE_CACHE_SIZE
  • DB_nK_CACHE_SIZE

Сумма значений данных параметров вычитается из sga_target.

Типы приложений

Типы приложений

  • OLTP (Online Transaction Processing) - приоритет на онлайн транзакции
  • DWH (Data Warehouse) - хранилище данных, приоритет на обработку больших объемов данных

Общие рекомендации

Для OLTP приложения:

  • 60% SGA_TARGET
  • 40% PGA_AGGREGATE_TARGET

Для DWH приложения:

  • 40% SGA_TARGET
  • 60% PGA_AGGREGATE_TARGET

Системные таблицы и представления

  • sys.v$parameter - текущие параметры
  • sys.v$osstat - ресурсы ОС
  • sys.v$sga_dynamic_components - текущее распределение памяти назначенное AMM
-- история динамического изменения параметров памяти
sys.V$MEMORY_RESIZE_OPS

-- история динамического изменения параметров памяти
sys.V$SGA_RESIZE_OPS

Параметры с префиксом "__" определяют текущее значение и могут отличаться от аналогичного параметра без этого префикса, который задает значение при старте инстанции

__db_cache_size - текущее значение
db_cache_size - начальное значение заданное в spfile/pfile

Пример скрипта для расчета значений параметров

DECLARE
    os_memory            number;
    granule_size         number;
    memory_target        number;
    sga_target           number;
    pga_aggregate_target number;
    iname                varchar2(16);
BEGIN
 
    SELECT VALUE/1024/1024/1024 into os_memory
    FROM   v$osstat
    WHERE  stat_name = 'PHYSICAL_MEMORY_BYTES';
    os_memory := ceil(os_memory) * 1024;
      
    -- for os_memory  <  10GB set only memory_target  
    -- os_memory :=  10*1024;   --  10GB
    -- os_memory :=  12*1024;   --  12GB
    -- os_memory :=  16*1024;   --  16GB
    -- os_memory :=  18*1024;   --  18GB
    -- os_memory :=  20*1024;   --  20GB
    -- os_memory :=  24*1024;   --  24GB
    -- os_memory :=  32*1024;   --  32GB
    -- os_memory :=  48*1024;   --  48GB
    -- os_memory :=  64*1024;   --  64GB
    -- os_memory := 100*1024;   -- 100GB
    -- os_memory := 128*1024;   -- 128GB
    -- os_memory := 192*1024;   -- 192GB
    -- os_memory := 256*1024;   -- 256GB

    select granule_size/1024/1024 into granule_size
    from v$sga_dynamic_components
    where component='DEFAULT buffer cache';
  
    select instance_name into iname from v$instance;

    if os_memory > 16384 then
       memory_target := os_memory - 4096;
    else
       memory_target := os_memory * 0.8;
    end if;

    sga_target := (memory_target * 0.6);
    sga_target := ceil(sga_target/granule_size)*granule_size;

    memory_target := ceil(memory_target/granule_size)*granule_size;

    pga_aggregate_target := memory_target - sga_target;

    DBMS_OUTPUT.PUT_LINE( '--'||os_memory/1024||'GB' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__db_cache_size"         scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__java_pool_size"        scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__large_pool_size"       scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__pga_aggregate_target"  scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__sga_target"            scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__shared_io_pool_size"   scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__shared_pool_size"      scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system reset "__streams_pool_size"     scope=spfile sid='''||iname||''';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system set memory_max_target    = ' ||memory_target||'M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system set memory_target        = ' ||memory_target||'M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system set sga_max_size         = ' ||sga_target||'M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system set sga_target           = ' ||sga_target||'M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( 'alter system set pga_aggregate_target = ' ||pga_aggregate_target||'M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( '--alter system reset pga_aggregate_target scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( '--alter system set db_cache_size      = 512M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( '--alter system set shared_pool_size   = 512M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( '--alter system set java_pool_size     = 128M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( '--alter system set large_pool_size    =  64M scope=spfile sid=''*'';' );
    DBMS_OUTPUT.PUT_LINE( '--alter system set streams_pool_size  =  64M scope=spfile sid=''*'';' );
END;
/

Разобраться

Смотрим значения параметров:

select     name || '=' || decode(type, 2, '''') || value
    || decode(type, 2, '''') parameter
from    v$parameter
where    isdefault = 'FALSE'
and    value is not null
order    by name
/


Распределение памяти экземпляра в режиме AMM:

col component format a20
break on report
compute sum of current_size_mb on report
select component, round(current_size/1024/1024,1) as current_size_mb
from v$memory_dynamic_components
where component like '%Target%';


Потребление памяти на уровне сессии

select *
from (
select
    p.spid,
    p.pid,
    s.sid,
    s.serial#,
    substr(trim(s.machine),1,32) machine,
    s.username,
    s.osuser,
    round(p.pga_used_mem/1024/1024,2) pga_used_mb,
    round(p.pga_alloc_mem/1024/1024,2) pga_alloc_mb,
    round(p.pga_max_mem/1024/1024,2) pga_max_mb,
    row_number() over (order by round(p.pga_max_mem/1024/1024,2) desc) as rn
from
   v$process p,
   v$session s
where p.addr = s.paddr
) where rn < 21
order by pga_max_mb desc;


Чтобы понять, является ли текущий размер SGA оптимальным, изучите следующие представления:

select * from V$SGA_DYNAMIC_COMPONENTS
select * from V$SGA_CURRENT_RESIZE_OPS
select * from V$SGA_RESIZE_OPS
select * from V$SGA_DYNAMIC_FREE_MEMORY


SELECT  component,
        current_size/1024/1024,
        min_size/1024/1024,
        max_size/1024/1024
FROM    v$memory_dynamic_components
WHERE   current_size != 0;


Для точной настройки значений механизма AMM можно использовать:

select * from V$MEMORY_TARGET_ADVICE

SELECT * FROM v$memory_target_advice ORDER BY memory_size;


Для настройки значений параметров SGA и PGA:

select * from V$SGA_TARGET_ADVICE
select * from V$PGA_TARGET_ADVICE



Примечание для OS Solaris:

Настройка AMM или ASMM на ОС Solaris заставит ОС использовать Dynamic Intimate Shared Memory (DISM).
Это позволяет динамически изменять размер shared memory segments.
Динамические свойства SGA используют DISM при включенном AMM или ASMM.
Начиная с Oracle 9i и выше, если SGA_MAX_SIZE  >  SGA_TARGET (или суммы sga compenents), тогда используется DISM.
В 11g DISM также используется, если установлен MEMORY_TARGET или MEMORY_MAX_TARGET.
В противном случае используется ISM (если DISM не включен).
DISM (в отличие от ISM) требует резервирования swap для всех страниц, независимо от того, выделены они или нет.
Это означает, что вам нужно будет настроить swap размером не менее чем сумма размеров SGA для экземпляров, использующих DISM.
Иначе получим memory errors при старте экземпляра.

Используется ли DISM для экземпляра Oracle, можно узнать так:

$ ps -aef | grep dis

должен быть процесс:
ora_dism_$ORACLE_SID

Избежать использования DISM и большого размера swap можно используя manual memory management.