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.