Oracle DB: Управление памятью
Ссылки по теме:
Linux HugePages
Ссылки по теме
Размер обычной страницы памяти 4 Кб, это создает большие накладные расходы, снижает производительность и значительный объем памяти тратится на огромные таблицы страниц памяти.
Ядро линукс поддерживает работу с HudgePages, размер которых может быть 2 Мб, а с аппаратной поддержкой размер страницы может быть 1 ГБ.
Важные факты
- Automatic Memory Management (AMM) - не совместим с Linux HugePages, не может управлять памятью более 4ГБ, поэтому этот режим можно применять только на очень мелких и не важных базах
- Automatic Shared Memory Management (ASMM) и Automatic PGA Management - совместимы с HugePages.
- Паять связанная с HudgePages не может быть выгружена в swap, поэтому SGA вынуждена постоянно находиться в памяти
- Использование HudgePages значительно повышает производительность Oracle 11g и выше, поэтому использовать это практически обязательно
Сам по себе большой SGA не создает проблем, но в сочетании с большим количеством сессий, размер таблицы памяти может стать слишком большим, что значительно снизит производительность
# определение размера таблиц памяти grep PageTables /proc/meminfo # проверка использования HudgePages grep Huge /proc/meminfo
Параметры инстанции
use_large_pages = TRUE | FALSE # по умолчанию TRUE # TRUE применимо только к платформе Linux, хотя FALSE может привести к деградации производительности и на других платформах
Скрипт для вычисления определения оптимальной конфигурации
- скрипт использует команду
ipcs -m
, которая выводит список сегментов разделяемой памяти и их размеры - определяет количество HudgePages страниц необходимых для размещения каждого сегмента и суммирует их
#!/bin/bash # # hugepages_setting.sh # # Linux bash script to compute values for the # recommended HugePages/HugeTLB configuration # # Note: This script does calculation for all shared memory # segments available when the script is run, no matter it # is an Oracle RDBMS shared memory segment or not. # Check for the kernel version KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'` # Find out the HugePage size HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}` # Start from 1 pages to be on the safe side and guarantee 1 free HugePage NUM_PG=1 # Cumulative number of pages required to handle the running shared memory segments for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"` do MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q` if [ $MIN_PG -gt 0 ]; then NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q` fi done # Finish with results case $KERN in '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`; echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;; '2.6' | '3.8' | '3.10' | '4.1' | '4.14' ) echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;; *) echo "Unrecognized kernel version $KERN. Exiting." ;; esac # End
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 = 2G scope=both; # можно менять динамически alter system set memory_max_target = 4G scope=spfile;
AMM включается только если задан параметр memory_target.
alter system set memory_target = 2G 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 = 4G 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 используют статистики, поэтому параметр инициализации 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.
Automatic PGA Management
Параметры
- pga_aggregate_limit - предел, выше которого не может вырасти суммарный PGA инстанции (отсутствует в 11.2.0.4, нужно уточнить в какой версии появился)
- pga_aggregate_target - целевое значение суммарного PGA инстанции к которому будет стремиться Automatic PGA Management, динамически управляя персональными областями PGA серверных процессов сессий и фоновых процессов
Реальный размер суммарного PGA (PGA Allocated) может значительно отличаться от pga_aggregate_target как в большую так и в меньшую сторону, т.к. зависит не только от размеров PGA отдельных процессов, но и от их количества.
Для ручного управления PGA необходимо определять размеры PGA для каждого типа запроса, это поддерживается, но не рекомендуется.
System Global Area (SGA)
SGA - это общая область памяти, которую используют все процессы инстанции
Program Global Area (PGA)
PGA - это совокупность областей памяти, выделяемых серверным процессам сессий и фоновым процессам инстанции, которые принадлежат только своим процессам и не разделяются между ними.
Типы приложений
Типы приложений
- 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.