Sidebar

Para identificar procesos con alto consumo de cpu podemos utilizar el comando ps para identificar el ID.

[oracle@m9 ~]$ ps -e -o pcpu,pid,user,tty,args | sort -n -k 1 -r|head

Para ver los procesos de oracle

[oracle@m9 ~]$ ps -e -o pcpu,pid,user,tty,args | grep -i oracle|sort -n -k 1 -r|head
8.2 2406 oracle ? oracleorc11g (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
3.6 30445 oracle ? oracleorc11g (LOCAL=NO)
0.1 30424 oracle ? oracleorc11g (LOCAL=NO)
0.0 3550 oracle ? oracleorc11g (LOCAL=NO)
0.0 30428 oracle ? oracleorc11g (LOCAL=NO)
0.0 30426 oracle ? oracleorc11g (LOCAL=NO)
0.0 30238 oracle ? oracleorc11g (LOCAL=NO)
0.0 29529 oracle ? oracleorc11g (LOCAL=NO)
0.0 29431 oracle ? oracleorc11g (LOCAL=NO)
0.0 2562 oracle pts/2 grep oracleorc11g

La primera columna nos da el porcentaje de CPU, la segunda es el ID del proceso. Con esta información podemos realizar una consulta a la base de datos para ver que es lo que se esta ejecutando en ella.

SET LINESIZE 80 HEADING OFF FEEDBACK OFF
SELECT
RPAD('USERNAME : ' || s.username, 80) ||
RPAD('OSUSER : ' || s.osuser, 80) ||
RPAD('PROGRAM : ' || s.program, 80) ||
RPAD('SPID : ' || p.spid, 80) ||
RPAD('SID : ' || s.sid, 80) ||
RPAD('SERIAL# : ' || s.serial#, 80) ||
RPAD('MACHINE : ' || s.machine, 80) ||
RPAD('TERMINAL : ' || s.terminal, 80) ||
RPAD('SQL TEXT : ' || q.sql_text, 80)
FROM v$session s
,v$process p
,v$sql q
WHERE s.paddr = p.addr
AND p.spid = '&PROCESS_ID'
AND s.sql_address = q.address
AND s.sql_hash_value = q.hash_value;

Si ejecutamos el query anterior con el proceso 2406 obtenemos:

USERNAME : SYS
OSUSER : oracle
PROGRAM : sqlplus@m9 (TNS V1-V3)
SPID : 2406
SID : 118
SERIAL# : 34927
MACHINE : m9
TERMINAL : pts/1
SQL TEXT : select count(*) from dba_objects

De esta manera, podemos identificar los procesos de oracle y sus sentencias SQL que están consumiendo más CPU en el servidor de base de datos.

Otra herramienta útil es el comando top, esta herramienta por default va a refrescar cada 3 segundos mostrando los procesos que consumen más CPU.

$ top
top - 11:46:28 up 7 days, 1:12, 1 user, load average: 0.64, 0.58, 0.61
Tasks: 253 total, 2 running, 251 sleeping, 0 stopped, 0 zombie
Cpu(s): 13.4%us, 4.3%sy, 0.0%ni, 81.5%id, 0.0%wa, 0.2%hi, 0.6%si, 0.0%st
Mem: 4063964k total, 3901752k used, 162212k free, 24544k buffers
Swap: 10241336k total, 177400k used, 10063936k free, 1196636k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
24028 oracle 20 0 1986m 412m 20m S 0.3 10.4 9:59.04 java
30424 oracle 20 0 1032m 199m 193m S 0.3 5.0 5:43.51 oracle
3550 oracle 20 0 1032m 50m 45m S 0.0 1.3 0:16.64 oracle
7043 oracle 20 0 2892 1120 956 S 0.0 0.0 0:00.92 nmz
15189 oracle 20 0 1026m 16m 13m S 0.0 0.4 0:00.03 oracle
18851 oracle 20 0 1032m 227m 220m S 0.0 5.7 2:47.52 oracle
23151 oracle 20 0 1032m 142m 136m S 0.0 3.6 0:07.50 oracle

La columna PID nos muestra el ID del proceso que esta consumiendo más CPU, en este caso 24028. Ahora mientras esta corriendo podemos modificar la salida, por ejemplo si presionamos >, se va a ordenar por la siguiente columna de la derecha en este caso %MEM. A continuación muestra una lista con las opciones que se tienen disponibles.

 

Barra Espaciadora

Refresca la salida

< o >

Cambia de columna a ordenar, por default es CPU.

d

Cambia el tiempo de refrescar la salida.

R

Invierte el orden.

z

Cambia el color de la salida.

h

Despliega el menu de ayuda.

F o O

Seleccionar una columna para ordenar.

Si requermios revisar algun proceso en particular podemos usar la opción -p o algun usuario en particular -U. Si queremos cambiar el tiempo de refresh a 5 y hacer 25 número distinto de iteraciones sería de la siguiente manera:

$top -U oracle -d 5 -n 25

 

Como identificar un cuello de botella en el CPU
La herramienta mpstat (multiple processor statistics) despliega estadísticas de los procesos en el server.

[oracle@m9 ~]$ mpstat
Linux 2.6.27.25-78.2.56.fc9.x86_64 (m9)         07/05/2010

08:50:39 AM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
08:50:39 AM  all   13.38    0.00    6.22    0.74    0.17    0.56    0.00   78.92   3169.71

Por default nos va a mostrar una línea donde se encuentra el promedio de todos los CPUs, pero también es posible mostrar un reporte que muestre estadísticas acumuladas entre intervalos, así como también seleccionar el CPU que se quiere monitorear a todos ellos. Por ejemplo si queremos monitorear solo el CPU 0 cada 5 segundos por un periodo de 10 intervalos se ejecuta de la siguiente manera:

[oracle@m9 ~]$ mpstat -P 0 5 10
Linux 2.6.27.25-78.2.56.fc9.x86_64 (m9)         07/05/2010

08:53:17 AM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
08:53:22 AM    0   11.86    0.00    2.17    0.20    0.00    0.00    0.00   85.77     99.20
08:53:27 AM    0   13.44    0.00    2.17    0.40    0.00    0.20    0.00   83.79    105.00
08:53:32 AM    0   20.68    0.00    2.58    2.19    0.00    0.00    0.00   74.55     99.60
08:53:37 AM    0   18.42    0.00    2.38    2.38    0.00    0.20    0.00   76.63    116.60
08:53:42 AM    0   18.09    0.00    5.17    1.39    0.00    0.00    0.00   75.35    122.80
08:53:47 AM    0   12.08    0.00    6.34    0.00    0.00    0.20    0.00   81.39    106.00
08:53:52 AM    0   12.85    0.00    1.98    0.20    0.00    0.00    0.00   84.98     95.00
08:53:57 AM    0   13.66    0.00    2.18    1.19    0.00    0.20    0.00   82.77     96.20
08:54:02 AM    0   12.48    0.00    2.77    0.59    0.00    0.00    0.00   84.16     98.80
08:54:07 AM    0   12.90    0.00    3.37    0.00    0.00    0.00    0.00   83.73     95.20
Average:       0   14.64    0.00    3.11    0.85    0.00    0.08    0.00   81.32    103.44

Si quisieramos ver todos los procesadores sería con la opción -P ALL

[oracle@m9 ~]$ mpstat -P ALL
Linux 2.6.27.25-78.2.56.fc9.x86_64 (m9)         07/05/2010

08:54:24 AM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
08:54:24 AM  all   13.39    0.00    6.22    0.74    0.17    0.56    0.00   78.92   3169.72
08:54:24 AM    0   13.53    0.00    5.51    0.62    0.00    0.07    0.00   80.27     94.52
08:54:24 AM    1   13.25    0.00    6.91    0.85    0.34    1.03    0.00   77.62    824.42

Para interpretar estos resultados de una manera rápida debemos de fijarnos principalmente en 2 columnas (%idel y %iowait). Si %idle es muy alto entonces no tenemos los procesadores sobrecargados. Si $iowait es un valor mayor a 0, posiblemente tengamos algo de contención en los discos. Si encontramos que tenemos los CPUs sobrecargados podemos usar, como se comento anteriormente ps o top para encontrar que procesos están afectando al servidor. De la misma manera que los comandos anteriores es posible guardar la salida en un archivo de texto:

[oracle@m9 ~]$ mpstat -P 0 5 10 > mpstat.out

Esta es una copia de lo que significa cada una de las columnas del reporte de salida de mpstat.

       CPU
              Processor number. The keyword all indicates that statistics are calculated as
              averages among all processors.
       %user
              Show  the  percentage of CPU utilization that occurred while executing at the
              user level (application).
       %nice
              Show the percentage of CPU utilization that occurred while executing  at  the
              user level with nice priority.
       %sys
              Show  the  percentage of CPU utilization that occurred while executing at the
              system level (kernel). Note that this does not include time  spent  servicing
              interrupts or softirqs.
       %iowait
              Show  the  percentage of time that the CPU or CPUs were idle during which the
              system had an outstanding disk I/O request.
       %irq
              Show the percentage of time spent by the CPU or CPUs to service interrupts.
       %soft
              Show the percentage of time spent by the CPU or CPUs to service softirqs.   A
              softirq  (software  interrupt)  is one of up to 32 enumerated software inter-
              rupts which can run on multiple CPUs at once.
       %steal
              Show the percentage of time spent in involuntary wait by the virtual  CPU  or
              CPUs while the hypervisor was servicing another virtual processor.
       %idle
              Show the percentage of time that the CPU or CPUs were idle and the system did
              not have an outstanding disk I/O request.
       intr/s
              Show the total number of interrupts received per second by the CPU or CPUs.

Otra herramienta muy útil para analizar el comportamiento del procesador de días anteriores es la herramienta sar (systrem activity reporter), este comando por default sólo nos va a reportar información del día actual. Para mostrar la información referente a CPU se debe ejecutar con la opción -u

[oracle@m9 ~]$ sar -u
Linux 2.6.27.25-78.2.56.fc9.x86_64 (m9)         07/05/2010

12:00:01 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
12:10:01 AM     all     11.99      0.00      5.12      1.04      0.00     81.84
12:20:01 AM     all     12.23      0.00     15.13      0.23      0.00     72.42
12:30:01 AM     all     12.29      0.00      7.81      0.23      0.00     79.66
12:40:01 AM     all     12.29      0.00      5.09      0.21      0.00     82.41
12:50:01 AM     all     12.31      0.00      5.28      0.13      0.00     82.29
01:00:01 AM     all     12.09      0.00     15.73      1.88      0.00     70.30
01:10:02 AM     all     12.25      0.00      7.01      6.38      0.00     74.36
01:20:01 AM     all     12.28      0.00      5.06      1.94      0.00     80.72
01:30:01 AM     all     12.08      0.00      4.79      0.18      0.00     82.95
01:40:01 AM     all     11.97      0.00      4.83      0.28      0.00     82.91
01:50:01 AM     all     12.08      0.00      4.90      0.18      0.00     82.84
02:00:01 AM     all     11.91      0.00      4.99      0.32      0.00     82.79
02:10:01 AM     all     11.95      0.00      6.36      0.44      0.00     81.25
02:20:01 AM     all     12.65      0.00     10.40      0.50      0.00     76.45
02:30:01 AM     all     12.32      0.00      4.85      0.28      0.00     82.55
02:40:01 AM     all     12.27      0.00      5.02      0.22      0.00     82.48
02:50:01 AM     all     12.45      0.00      5.01      0.22      0.00     82.32
03:00:01 AM     all     12.26      0.00      6.85      0.47      0.00     80.42
03:10:02 AM     all     12.31      0.00      4.99      0.28      0.00     82.42
03:20:01 AM     all     11.86      0.00      4.91      0.14      0.00     83.09
03:30:01 AM     all     12.07      0.00      4.95      0.17      0.00     82.81
03:40:01 AM     all     11.94      0.00      5.72      0.29      0.00     82.05
03:50:01 AM     all     12.11      0.00      5.04      0.14      0.00     82.71

Si lo que nos interesa es ver información anterior, debemos utilizar la opción -f. Los archivos que sar utiliza para generar el reporte se localizan en /var/log/sa y tienen la convención de saNN, donde NN son los dos días del mes.

[oracle@m9 sa]$ pwd
/var/log/sa
[oracle@m9 sa]$ ls -la
total 12836
drwxr-xr-x  2 root root   4096 2010-07-05 00:00 .
drwxr-xr-x 21 root root   4096 2010-07-05 05:02 ..
-rw-r--r--  1 root root 689712 2010-07-01 23:50 sa01
-rw-r--r--  1 root root 689712 2010-07-02 23:50 sa02
-rw-r--r--  1 root root 689712 2010-07-03 23:50 sa03
-rw-r--r--  1 root root 689712 2010-07-04 23:50 sa04
-rw-r--r--  1 root root 263580 2010-07-05 09:00 sa05
-rw-r--r--  1 root root 689712 2010-06-27 23:50 sa27
-rw-r--r--  1 root root 689712 2010-06-28 23:50 sa28
-rw-r--r--  1 root root 689712 2010-06-29 23:50 sa29
-rw-r--r--  1 root root 689712 2010-06-30 23:50 sa30
-rw-r--r--  1 root root 804152 2010-07-01 23:53 sar01
-rw-r--r--  1 root root 804152 2010-07-02 23:53 sar02
-rw-r--r--  1 root root 804152 2010-07-03 23:53 sar03
-rw-r--r--  1 root root 804152 2010-07-04 23:53 sar04
-rw-r--r--  1 root root 800031 2010-06-26 23:53 sar26
-rw-r--r--  1 root root 804152 2010-06-27 23:53 sar27
-rw-r--r--  1 root root 804152 2010-06-28 23:53 sar28
-rw-r--r--  1 root root 804152 2010-06-29 23:53 sar29
-rw-r--r--  1 root root 804152 2010-06-30 23:53 sar30

Por ejemplo si nos interesa ver el día 30 de junio ejecutamos lo siguiente:

[oracle@m9 sa]$ sar -u -f /var/log/sa/sa30
Linux 2.6.27.25-78.2.56.fc9.x86_64 (m9)         06/30/2010

12:00:01 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
12:10:01 AM     all     11.34      0.00      5.28      0.12      0.00     83.26
12:20:01 AM     all     11.89      0.00      3.70      0.09      0.00     84.31
12:30:01 AM     all     11.48      0.00      3.43      0.10      0.00     84.99
12:40:01 AM     all     11.28      0.00      3.53      0.08      0.00     85.10
12:50:01 AM     all     11.47      0.00      3.57      0.10      0.00     84.86
.
.
.
11:40:01 PM     all     12.84      0.00      4.16      0.30      0.00     82.70
11:50:01 PM     all     12.69      0.00      4.53      0.23      0.00     82.55
Average:        all     16.73      0.00      4.53      0.92      0.00     77.81

Cuando instalamos el paquete sysstat, se instalan dos crones que generar los archivos utilizados por el comando sar, estos se encuentran en /etc/cron.d/sysstat

[root@m9 cron.d]# pwd
/etc/cron.d

[root@m9 cron.d]# cat sysstat
# Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 -d 1 1
# 0 * * * * root /usr/lib64/sa/sa1 -d 600 6 &
# Generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A

 

Las dos columnas importantes a revisar, son las mismas que mpstat (%idel y %iowait) Si llegamos a encontrar algún reporte que indique que el CPU se encontraba sobrecargado podemos generar un reporte AWR de oracle (Automatic Workload Repository) para el mismo periodo en que nos lo indica el reporte de sar, recordemos que por default oracle solo guarda información de 7 días de snapshots. Para los que no recuerdan como generar estos reportes desde sqlplus solo tenemos que ejecutar el script awrrpt.sql como se muestra a continuación:

 

[oracle@m9 db_1]$ sqlplus / as sysdba

SQL*Plus: Release 11.1.0.7.0 - Production on Mon Jul 5 10:59:27 2010

Copyright (c) 1982, 2008, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @?/rdbms/admin/awrrpt.sql

Existen otros reportes como el ADDM(Database Diagnostic Monitor) addmrpt.sql y ASH (Active Session History) ashrpt.sql que pueden ayudarnos a diagnosticar un problema de CPU.


Tips BD