En Oracle Linux (y en general en sistemas Linux), TS (Time Sharing) y RR (Round Robin) son dos tipos de políticas de planificación de procesos (scheduling policies) que definen cómo el kernel decide cuándo y cuánto tiempo ejecuta un proceso en la CPU.
TS - Time Sharing (SCHED_OTHER)
-
Es la política por defecto para los procesos normales (no tiempo real).
-
Diseñada para equilibrar el uso de CPU entre muchos procesos de forma justa.
-
Usa un algoritmo de prioridad dinámica, es decir:
-
Si un proceso consume mucha CPU, su prioridad puede bajar temporalmente.
-
Si está inactivo (esperando E/S), puede ganar prioridad.
-
Ideal para entornos multitarea tradicionales donde se busca mantener buena respuesta del sistema.
🔹 Ejemplo: procesos de usuario, shell scripts, editores de texto, sesiones SQL*Plus, etc.
RR - Round Robin (SCHED_RR)
-
Es una política de tiempo real.
-
Usa prioridades fijas (estáticas) entre 1 y 99 (más alta = más prioridad).
-
Todos los procesos con la misma prioridad se ejecutan en orden, uno después del otro, por intervalos de tiempo iguales (el "quantum").
-
No se ajusta automáticamente como TS.
-
Debe ser usado con precaución, porque puede acaparar la CPU y afectar procesos normales.
🔹 Ejemplo: procesos críticos de tiempo real, como servicios industriales, controladores de dispositivos en baja latencia, etc.
Cuando un proceso se ejecuta en RR (Tiempo real) su prioridad es fija entre un valor 1 y 99 y la característica de "justicia" o convivencia con otros procesos es baja, lo que puede producir que se bloqueen otros procesos. También se corre el riesgo , de que se acapare el CPU si se utiliza mal.
En Oracle Database, dependiendo de la versión que estés utilizando y las características configuradas, puedes tener una cantidad importante de procesos background ejecutándose.
Puedes validar la información de los procesos en ejecución a través de una consulta a la vista dinámica V$PROCESS.
Hablemos de 3 de ellos que es común encontrar en nuestros servidores: LMS, VKTM y LGWR
LMS – Lock Manager Server Process
➤ Función principal:
LMS es el proceso clave del subsistema de Oracle RAC (Real Application Clusters). Se encarga de la gestión de bloqueos globales (Global Cache Management) y coherencia de buffer entre instancias.
➤ Roles y responsabilidades:
-
Coordina los accesos a bloques de datos compartidos entre nodos RAC.
-
Si un nodo necesita un bloque que otro nodo posee en su buffer cache, LMS orquesta la transferencia.
-
Usa GCS (Global Cache Services) y GES (Global Enqueue Services).
➤ Escenario típico:
Cuando una sesión en el nodo A necesita leer un bloque actualizado en el nodo B:
-
Se genera una solicitud remota.
-
LMS de ambos nodos se comunican.
-
Se transfiere el bloque actualizado, asegurando consistencia.
➤ Importancia en rendimiento:
VKTM – Virtual Keeper of Time
➤ Función principal:
VKTM mantiene la precisión del tiempo interno de la instancia de base de datos Oracle.
➤ Roles y responsabilidades:
-
Proporciona una referencia de tiempo altamente precisa para los procesos internos.
-
Sincroniza los timestamps usados en trace files, diagnósticos, ejecución de SQL, etc.
-
Reduce el número de llamadas al sistema operativo para obtener el tiempo (gettimeofday()), mejorando el rendimiento.
➤ Escenario típico:
Cuando múltiples procesos necesitan timestamps (por ejemplo, para medir latencias), en lugar de llamar directamente al sistema operativo, obtienen la hora desde VKTM, que actúa como reloj compartido.
➤ Importancia:
LGWR – Log Writer
➤ Función principal:
LGWR escribe los redo entries (registros de cambios) desde el log buffer en la SGA hacia los redo log files en disco.
➤ Roles y responsabilidades:
-
Asegura la durabilidad de las transacciones: cuando una transacción hace COMMIT, LGWR garantiza que sus cambios están en disco.
-
Escribe en los archivos redo log en:
➤ Escenario típico:
Durante una transacción:
-
Los cambios se almacenan en el log buffer.
-
Al ejecutar COMMIT, el proceso de usuario espera hasta que LGWR escriba esos cambios al archivo redo log.
-
Luego se confirma el COMMIT al cliente.
➤ Importancia en recuperación y performance:
-
En caso de fallo, Oracle usa los redo logs para recuperar los cambios no grabados en los datafiles.
-
LGWR debe ser rápido: el almacenamiento de redo logs debería ser de alta velocidad y baja latencia.
En Oracle Database 19c E.E., 19.27, el proceso VKTM corre en tiempo real (RR):
SQL> host ps -eo pid,class,pri,nice,time,args |grep vktm
20624 RR 41 - 00:34:51 ora_vktm_cdb
189777 TS 19 0 00:00:00 /bin/bash -c ps -eo pid,class,pri,nice,time,args |grep vktm
189779 TS 19 0 00:00:00 grep vktm
Pero en el caso del resto de procesos, lo hacen en tiempo compartido.
SQL> host ps -eo pid,class,pri,nice,time,args |grep ora_lg*
20666 TS 19 0 00:00:26 ora_lgwr_cdb
20674 TS 19 0 00:00:02 ora_lg00_cdb
20680 TS 19 0 00:00:02 ora_lg01_cdb
20688 TS 19 0 00:00:10 ora_lreg_cdb
189780 TS 19 0 00:00:00 /bin/bash -c ps -eo pid,class,pri,nice,time,args |grep ora_lg*
189782 TS 19 0 00:00:00 grep ora_lg*
Como hemos mencionado en líneas previas, el LGWR y el proceso LMS podrían ser sumamente críticos para un sistema con alta demanda, pero se ejecutan en tiempo compartido (TS).
Como ya he mencionado en muchas notas anteriores, Oracle Database tiene una gran cantidad de parámetros de configuración, llamados "OCULTOS" que pueden ser configurados con ayuda del equipo técnico del MOS, si se llegan a presentar inconvenientes como cuellos de botella.
En este caso, vamos a hablar de "high_priority_processes" que puede ser utilizado, para cambiar la prioridad de ejecución de un proceso de la base de datos.
Recuerden que esto primero debe ser bien analizado y altamente recomendado probar inicialmente en un ambiente de testeo.
Lo primero que tenemos que hacer es validar si el parámetro ha sido previamente configurado. Si no existe vamos a declararlo en el archivo de parámetros SPFILE. Este párametro no es dinámico, por lo que será necesario reiniciar la base de datos para que tome efecto.
SQL> show parameter high
SQL> alter system set "_high_priority_processes"='LMS*|VKTM|LGWR' scope=spfile;
System altered.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> exit
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.27.0.0.0
[oracle@laboratorio-investigacion admin]$ sqlplus /nolog
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 25 22:16:00 2025
Version 19.27.0.0.0
Copyright (c) 1982, 2024, Oracle. All rights reserved.
SQL> connect / as sysdba
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area 1.2281E+10 bytes
Fixed Size 9191424 bytes
Variable Size 1912602624 bytes
Database Buffers 1.0335E+10 bytes
Redo Buffers 24363008 bytes
Database mounted.
Database opened.
SQL> show parameter high
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_high_priority_processes string LMS*|VKTM|LGWR
SQL> host ps -eo pid,class,pri,nice,time,args |grep vktm
189903 RR 41 - 00:00:00 ora_vktm_cdb
190227 TS 19 0 00:00:00 /bin/bash -c ps -eo pid,class,pri,nice,time,args |grep vktm
190229 TS 19 0 00:00:00 grep vktm
SQL> host ps -eo pid,class,pri,nice,time,args |grep ora_lg*
189945 RR 41 - 00:00:00 ora_lgwr_cdb
189955 TS 19 0 00:00:00 ora_lg00_cdb
189961 TS 19 0 00:00:00 ora_lg01_cdb
189969 TS 19 0 00:00:00 ora_lreg_cdb
190232 TS 19 0 00:00:00 /bin/bash -c ps -eo pid,class,pri,nice,time,args |grep ora_lg*
190234 TS 19 0 00:00:00 grep ora_lg*
Como pueden observar, ahora el proceso LGWR se encuentra corriendo en tiempo real (RR).
Existe alguna información importante de monitoreo que podemos obtener directamente desde el director de procesos del sistema operativo /proc, relacionados con los procesos en ejecución.
Para encontrar la información que necesitamos de un proceso, tomamos el ID del proceso y lo ponemos a continuación de la ruta /proc.
SQL> host ps -eo pid,class,pri,nice,time,args |grep ora_lg*
189945 RR 41 - 00:00:00 ora_lgwr_cdb
189955 TS 19 0 00:00:00 ora_lg00_cdb
189961 TS 19 0 00:00:00 ora_lg01_cdb
189969 TS 19 0 00:00:00 ora_lreg_cdb
190232 TS 19 0 00:00:00 /bin/bash -c ps -eo pid,class,pri,nice,time,args |grep ora_lg*
190234 TS 19 0 00:00:00 grep ora_lg*
SQL> host
[oracle@laboratorio-investigacion admin]$ cd /proc
[oracle@laboratorio-investigacion proc]$ cd 189945
[oracle@laboratorio-investigacion 189945]$ ls -la
total 0
dr-xr-xr-x. 9 oracle oinstall 0 Apr 25 22:16 .
dr-xr-xr-x. 290 root root 0 Apr 22 00:20 ..
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 arch_status
dr-xr-xr-x. 2 oracle oinstall 0 Apr 25 22:18 attr
-r--------. 1 oracle oinstall 0 Apr 25 22:18 auxv
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 cgroup
--w-------. 1 oracle oinstall 0 Apr 25 22:18 clear_refs
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 cmdline
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 comm
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 coredump_filter
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 cpu_resctrl_groups
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 cpuset
lrwxrwxrwx. 1 oracle oinstall 0 Apr 25 22:18 cwd -> /opt/app/oracle/product/19c/dbs
-r--------. 1 oracle oinstall 0 Apr 25 22:18 environ
lrwxrwxrwx. 1 oracle oinstall 0 Apr 25 22:16 exe -> /opt/app/oracle/product/19c/bin/oracle
dr-x------. 2 oracle oinstall 0 Apr 25 22:16 fd
dr-xr-xr-x. 2 oracle oinstall 0 Apr 25 22:18 fdinfo
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 gid_map
-r--------. 1 oracle oinstall 0 Apr 25 22:16 io
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 limits
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 loginuid
dr-x------. 2 oracle oinstall 0 Apr 25 22:18 map_files
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 maps
-rw-------. 1 oracle oinstall 0 Apr 25 22:18 mem
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 mountinfo
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 mounts
-r--------. 1 oracle oinstall 0 Apr 25 22:18 mountstats
dr-xr-xr-x. 55 oracle oinstall 0 Apr 25 22:18 net
dr-x--x--x. 2 oracle oinstall 0 Apr 25 22:16 ns
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 numa_maps
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 oom_adj
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 oom_score
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:16 oom_score_adj
-r--------. 1 oracle oinstall 0 Apr 25 22:18 pagemap
-r--------. 1 oracle oinstall 0 Apr 25 22:18 personality
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 projid_map
lrwxrwxrwx. 1 oracle oinstall 0 Apr 25 22:18 root -> /
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 sched
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 schedstat
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 sessionid
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 setgroups
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 smaps
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 smaps_rollup
-r--------. 1 oracle oinstall 0 Apr 25 22:18 stack
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 stat
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 statm
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 status
-r--------. 1 oracle oinstall 0 Apr 25 22:18 syscall
dr-xr-xr-x. 3 oracle oinstall 0 Apr 25 22:18 task
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 timens_offsets
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:18 timers
-rw-rw-rw-. 1 oracle oinstall 0 Apr 25 22:18 timerslack_ns
-rw-r--r--. 1 oracle oinstall 0 Apr 25 22:18 uid_map
-r--r--r--. 1 oracle oinstall 0 Apr 25 22:16 wchan
[oracle@laboratorio-investigacion 189945]$ more sched
ora_lgwr_cdb (189945, #threads: 1)
-------------------------------------------------------------------
se.exec_start : 338122544.299222
se.vruntime : -5.974001
se.sum_exec_runtime : 70.000650
se.nr_migrations : 1
nr_switches : 1435
nr_voluntary_switches : 1432
nr_involuntary_switches : 3
se.load.weight : 1048576
se.avg.load_sum : 42637
se.avg.runnable_sum : 11051218
se.avg.util_sum : 10976185
se.avg.load_avg : 922
se.avg.runnable_avg : 233
se.avg.util_avg : 231
se.avg.last_update_time : 337975686315008
se.avg.util_est.ewma : 243
se.avg.util_est.enqueued : 231
policy : 2
prio : 98
clock-delta : 60
mm->numa_scan_seq : 0
numa_pages_migrated : 0
numa_preferred_nid : -1
total_numa_faults : 0
current_node=0, numa_group_id=0
numa_faults node=0 task_private=0 task_shared=0 group_private=0 group_shared=0
Los valores de variables del contenido del archivo pueden variar.
El archivo /proc/<PID>/sched en sistemas Linux (como Oracle Linux) contiene información detallada del planificador (scheduler) del kernel para un proceso específico. Este archivo es extremadamente útil para análisis de rendimiento, especialmente en entornos donde quieres investigar cómo el kernel ha gestionado un proceso individual.
El archivo SCHED, es un archivo de texto generado dinámicamente por el kernel que contiene métricas relacionadas con:
Explicación de los campos clave:
Campo Descripción
bash (1234, #threads: 1) Nombre del proceso, PID y número de threads
se.exec_start Timestamp del último inicio de ejecución (en nanosegundos desde el arranque del sistema)
se.vruntime Tiempo de CPU utilizado, ajustado por peso (usado en CFS para decisiones de scheduling)
se.sum_exec_runtime Total de tiempo en CPU en nanosegundos
nr_switches Total de cambios de contexto realizados
nr_voluntary_switches Cambios de contexto voluntarios (por espera o sleep)
nr_involuntary_switches Cambios de contexto forzados por el scheduler
nr_wakeups Cantidad de veces que fue despertado desde estado de sleep
se.avg.last_update_time Última vez que se actualizaron los promedios del proceso (en nanosegundos)
se.avg.load_sum Suma acumulada del peso (carga) del proceso desde el último reinicio del promedio
se.avg.runnable_avg_sum Suma del tiempo que el proceso estuvo listo para correr (runnable)
se.avg.runnable_avg_period Período total en que se ha observado la “runnable average”
se.avg.util_avg Promedio de utilización de CPU por parte del proceso (base para CPU utilization tracking)
se.avg.load_avg Promedio móvil de carga del proceso, ajustado por peso (weight)
se.avg.decay_count Cuántas veces se ha aplicado el factor de decaimiento exponencial a los promedios
Algunos de los valores de estos parámetros nos ayuda a validar si un proceso espera mucho tiempo por disco o red como lo hace iowait_sum.
Comparar los valores de sum_exec_runtime entre procesos te muestra quién ha consumido más CPU realmente.
Si nr_involuntary_switches es alto el kernel está forzando al proceso a dejar la CPU.
El campo se.avg.last_update_time es sumamente importante. Este parámetro muestra el timestamp en nanosegundos que indica cuándo fue la última vez que se actualizó la información promedio del proceso, particularmente los promedios que el Completely Fair Scheduler (CFS) usa para calcular la equidad y el reparto de tiempo de CPU.
Mi recomendación es buscar la información oficial relacionada con tu versión de sistema operativo, para conocer más, de como esta ejecutándose los procesos en tu servidor o servicio, que aloja a tu base de datos.
No olviden por favor, implementar este tipo de cambios en ambientes controlados, antes de aplicar en producción.