How to identify Memory Botlenecks on Oracle Linux

Parecido com o artigo sobre consumo de CPU, hoje escreverei sobre consumo de memória, contemplando parte teórica e prática.

Basic Concepts

Quando observamos algumas informações sobre memória, é importante ter noção que:

  • Total = Memória total instalada e reconhecida pelo S.O
  • Used = Memória total usada no S.O, incluindo Buffer e Cache
  • Free = Reserva de memória livre disponível para uso
  • Buffers = espaço utilizado pelo Kernel, em caráter temporário, para otimizar operações internas
  • Cache = memória usada como cache para leitura de arquivos lidos do disco, melhorando assim a performance de I/O. Uma maneira de ver essa diferença foi demonstrada NESTE artigo do nosso blog.

Temos essas informações dispostas no man abaixo e no Oracle Note “Oracle Linux: System Memory Utilization (Doc ID 1514705.1)“:

How to Calculate Memory Usage

Uma vez com os conceitos teóricos, podemos evoluir.

Quando observamos o comando free, podemos ter a tendência de considerar a coluna free como o valor de memória livre disponível no servidor (e que em muitos casos, está muito baixa):

[oracle@oel7 ~]$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15772        1152       12360        1147        2259       13307
Swap:          1231           0        1231

O grande erro aqui é não considerar os valores de Buffer e Cache, pois o Linux reutiliza essas áreas de memória durante suas operações. Ou seja, o cálculo correto deveria ser: Free + Buffer + Cache.

Top 10 users and processes are consuming memory on system

Caso seja identificado que há algum problema na camada de memória do servidor, é possível verificar através do comando abaixo os Top 10 Users em porcentagem de consumo. No exemplo temos 32.70% do usuário oracle e 12.40% do grid.

# ps -eo user,pcpu,pmem | tail -n +2 | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{printf("NPROC\tUSER\tCPU\tMEM\n"); for (user in cpu) printf("%d\t%s\t%.2f\t%.2f\n",num[user], user, cpu[user], mem[user]) }'
[oracle@oel7 ~]$ ps -eo user,pcpu,pmem | tail -n +2 | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{printf("NPROC\tUSER\tCPU\tMEM\n"); for (user in cpu) printf("%d\t%s\t%.2f\t%.2f\n",num[user], user, cpu[user], mem[user]) }'
NPROC   USER    CPU     MEM
32      grid    4.20    12.40
1       rpc     0.00    0.00
83      oracle  2.00    32.70
1       colord  0.00    0.00
1       rtkit   0.00    0.00
1       polkitd 0.00    0.00
1       dbus    0.00    0.00
1       nobody  0.00    0.00
31      gdm     0.20    1.90
1       libstor+        0.00    0.00
2       avahi   0.00    0.00
2       postfix 0.00    0.00
177     root    0.00    0.40
[oracle@oel7 ~]$

Para identificar os processos que mais consomem memória, podemos usar:

ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS| tail -10
[oracle@oel7 ~]$ ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS| tail -10
114656 4347 oracle   ora_cjq0_cortex
115364 3065 grid     /grid/19.3.0/product/bin/ohasd.bin reboot
134704 3596 grid     /grid/19.3.0/product/bin/oraagent.bin
138544 23266 oracle  ora_m003_cortex
151368 4107 oracle   ora_mman_cortex
191948 3162 gdm      /usr/bin/gnome-shell
223320 4160 oracle   ora_mmon_cortex
250180 4180 oracle   ora_m000_cortex
285352 4694 oracle   ora_m005_cortex
306536 4579 oracle   ora_m002_cortex
[oracle@oel7 ~]$

Definição de cada coluna, conforme Oracle Note “Oracle Linux: How to Calculate Memory Usage (Doc ID 1630754.1)“: First column is RSS, second one is PID, the third one is USER and fourth is Command Executed – to sum-up first column only and give total in KB allocation, below command can be used:

ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS|  awk '{total += $1} END{print"sum="total}'
[oracle@oel7 ~]$ ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS|  awk '{total += $1} END{print"sum="total}'
sum=10009904

Swap Space Usage

A depender das operações que executam no servidor, pode ocorrer da área de memória não ser suficiente (ou seja, naquela dinâmica de carregar dados de disco para memória, e memória para disco, não conseguir dar vazão). Para estas ocasiões, o Linux utiliza da área de Swap, que em caráter temporário faz a função de “memória”. Quando esses eventos ocorrem de forma pontual, não é um problema, mas caso percebamos que a situação fica prolongada, isso acarreta sérios problemas de performance.

A manifestação dessas ocorrências podem ser vistas a partir da ferraments vmstat, nas colunas SI e SO:

Segundo o Oracle Note “Oracle Linux: How to Check Whether a System is Under Memory Pressure (Doc ID 1502301.1)“, os eventos de SO (Memória para Disco) podem ser normais e esperados: When an application requests memory from the operating system, it does not specify swap or physical memory, it just requests memory, the operating system manages the allocation of memory and use of swap.

Para identificar eventos anômalos: as colunas SI e SO precisam estar com valores acima de 0 de maneira prolongada. No exemplo abaixo, temos um ambiente sem problemas de memória:

[oracle@oel7 ~]$ vmstat 1 10 -S m
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0   5664      9   1815    0    0    41     0  697  556 13  6 64 17  0
 0  0      0   5640      9   1823    0    0   173     0 2768 2070  8  7 83  2  0
 2  0      0   5584      9   1826    0    0     0     0 3192 2032  4  8 87  1  0
 0  0      0   5553      9   1848    0    0     4     0 5109 6138 10  6 81  4  0
 0  0      0   5551      9   1848    0    0  2257     0 1692 1812  1  1 94  4  0
 0  0      0   5547      9   1852    0    0   228     0 1095 1251  0  1 98  1  0
 0  0      0   5542      9   1852    0    0     0     0 1208 1367  1  1 98  0  0
 0  0      0   5542      9   1852    0    0   156     0  970 1236  0  0 99  0  0
 0  0      0   5541      9   1852    0    0     0     0  935 1317  0  0 99  0  0
 1  1      0   5541      9   1852    0    0     0     0 1262 1330  1  1 98  0  0
[oracle@oel7 ~]$

Stressando o ambiente:

[root@oel7 ~]# stress --cpu 1 --vm 12 --vm-bytes 900M --timeout 60s
[oracle@oel7 ~]$ vmstat 1 10 -S m
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 5 42   1267   4627      2   1370    1    0  1305     6  689  460  9 15 36 39  0
 2 44   1274   4625      2   1374    6    0  6352    92 3107 2346  1  3  0 96  0
 1 37   1286   4636      2   1370   13    0 12796   131 4525 2608  0  3  0 96  0
 0 34   1291   4647      2   1366    6    0  6544    97 4748 3118  0  2  0 97  0
 1 34   1259   5553      2   1374    4    0  4711   102 4223 3440  1  6  0 93  0
 0 32   1264   5554      2   1372    5    0  5112   139 3923 3235  1  2  0 97  0
 0 38   1276   5564      2   1369   12    0 11776    88 3374 2787  0  3  0 97  0
 0 35   1287   5577      2   1361   12    0 12360   111 4083 3095  0  3  0 97  0
 3 34   1291   5582      2   1358    5    0  5485   176 4090 3396  0  2  0 98  0
 0 36   1291   5589      2   1356    0    0   944   271 4285 3923  1  4  0 96  0
[oracle@oel7 ~]$

Vemos que a coluna SI ficou com números acima de 0, além do Load da máquina também ter sido comprometido (o que é esperado quando isso ocorre).

Em suma, para diagnosticar problemas comuns de memória em servidores, é aconselhado validar se o mesmo está lidando com uso constante de Swap, o que pode significar que a memória física alocada está insuficiente para a carga executada, ou pode existir algum processo que está fazendo consumo demasiado de memória, e deve ser revisto. Referência:

https://docs.oracle.com/en/learn/ol-monitoring/index.html#explore-and-use-vmstat-command-options

Leave a Comment

Your email address will not be published.