Acerca de admin

Tras más de 20 años trabajando con tecnologías Oracle, me decidí a recopilar en un Blog algunas de las cosillas útiles para el día a día.

Parametrizacion del kernel en linux: swappiness

Hoy vamos a ver una parámetro poco documentado de la relaccion entre Linux y Oracle.
Cuando miramos las recomendaciones de Oracle para el kernel a la hora de instalarlo en un sistema operativo Linux nos encontramos con:
Configuring Kernel Parameters and Resource Limits

fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048586

Pero no hay ni rastro de este parámetro swappiness al que hago referencia. Si miramos en la wikipedia nos indica que :

Swappiness es una propiedad del Núcleo Linux que permite establecer un balance entre el uso del Espacio de intercambio (swap en inglés, por eso el nombre de la propiedad) y la Memoria de acceso aleatorio (RAM).
El swappiness puede tomar valores desde el 0 hasta el 100. Si se establece 0 el núcleo intentará no hacer intercambio, mientras que si se establece 100 el sistema intentará mantener la Memoria de acceso aleatorio lo más libre posible haciendo intercambio.

Este valor está configurado por defecto en las distribuciones Linux a 60 ,y como os decía no encontramos apenas referencias a el en la documentación de Oracle.Pero ¿que significa este valor del swappines a 60?

Significa que, cuando lleguemos al uso de ese 60% de memoria el proceso kswapd se lanzará a hacer su trabajo, haciendo que el rendimiento de nuestra base de datos caíga en picado por el uso de recursos del sistema del proceso kswapd.

¿Que hacer si esto ocurre?

La solucion pasa por modificar este parámetro para que el kswapd no empiece hasta un 10% de memoria libre.

echo vm.swappiness=10 >> /etc/sysctl.conf
sysctl -p

Como os comentaba, esta opcion del kernel de linux está muy poco documentada por parte de Oracle, yo solamente he encontrado referencias a ella en:

ORA-02020: too many database links in use

Hoy vamos a ver otra de esas entradas sencillas que nos pueden ahorra mucho tiempo.

Uno de los errores que podemos encontrarnos cuando trabajamos con DBlinks es

ORA-02020: too many database links in use

Esto puede ser facilmente solucionable con los parámetros del init.ora

open_links=500
open_links_per_instance=500

Como siempre, la informacion la tenemos en oracle :

Cambios en el arranque de Linux : systemctl

En la nueva versión de Oracle Linux (y RedHat) han optado por eliminar el tradicional método de arranque de servicios de /etc/init.d por el uso de systemctl.

Esta nueva funcionalidad cambia totalmente la manera de trabajar con los ficheros de arranque y parada de los servicios y, entre las supuestas virtudes de este sistema , personalmente no ha ninguna que me convezca.

En cualquier caso En esta web Uso de services de RedHat tenemos la información del funcionamiento de los comandos.

A modo de «bookmark» hago un copy & paste de dos tablas de ese documento que pueden sernos de utilidad

Correspondencia entre service y systemctl

Comparison of the service Utility with systemctl

Correspondencia entre chconfig y systemctl

omparison of the chkconfig Utility with systemctl

Obtener informacion del alert

Hoy vamos a ver una entrada muy rápida sobre alguna información albergada en el alert.log

Como hemos hablado en alguna entrada anterior , las versiones 11 y 12 de Oracle disponen de una vista con la información del alert.log, ¿de que nos sirve esto?
Pues puede sernos muy útil para obtener mediante consultas SQL algunos patrones, por ejemplo

Veces que se ha hecho un ALTER en lo que llevamos de año

select    
 ORIGINATING_TIMESTAMP,
 MESSAGE_TEXT
    from sys.x$dbgalertext
where  ORIGINATING_TIMESTAMP >
      TO_TIMESTAMP('01-01-14 00:00:00','DD-MM-RR HH24:MI:SS')
 and ( MESSAGE_TEXT like 'ALTER%')

Podemos filtrar mucho mas, por ejemplo , quitando las opciones de rman
Veces que se ha hecho un ALTER en lo que llevamos de año quitando el rman

 
 select    
   ORIGINATING_TIMESTAMP,
   MESSAGE_TEXT
     from sys.x$dbgalertext
   where  ORIGINATING_TIMESTAMP >
      TO_TIMESTAMP('01-01-14 00:00:00','DD-MM-RR HH24:MI:SS')
     and module_id not in ('rman')
     and ( MESSAGE_TEXT like 'ALTER%')
    and( MESSAGE_TEXT not like 'ALTER DATABASE BACKUP CONTROLFILE TO %')

O si queremos ver las veces que se ha llevado a cabo un evento concreto como arrancado la base de datos
Veces que se ha hecho un ALTER DATABASE OPEN

 select    
   ORIGINATING_TIMESTAMP,
   MESSAGE_TEXT
     from sys.x$dbgalertext
   where  ORIGINATING_TIMESTAMP > 
         TO_TIMESTAMP('01-01-14 00:00:00','DD-MM-RR HH24:MI:SS')
 and( MESSAGE_TEXT like 'ALTER DATABASE OPEN%')  
 

Como decía al principio, es una entrada muy sencilla, pero que, puede aportarnos información útil en muchos casos

Para un job de impdp de manera correcta

Hoy vamos a ver otra de esas entradas útiles del día a día.

En la entrada eliminar datapumps fallidos vimos como borrar los trabajos de impdp/expdp que estaban en entado fallido. Pero ¿que ocurre si queremos detener un trabajo en ejecución ?

Lo primero que haremos es volver a usar la consulta para ver el estado de los trabajos.

SET lines 200
SELECT owner_name, job_name, operation, job_mode,
state, attached_sessions
FROM dba_datapump_jobs
ORDER BY 1,2;

Y vemos que tenemos un JOB en modo de ejecucion

OWNER_NAME JOB_NAME    OPERATION JOB_MODE  STATE  ATTACHED
———- ——————- ——— ——— ———– ——–
SCOTT      EXPORT_TABLA_1 EXPORT  TABLE   EXECUTING  0
SYSTEM     EXPORT_DIARIA  EXPORT FULL     NOT RUNNING 0

Si lo que queremos es detener ese trabajo EXPORT_TABLA_1 de manera correcta, ejecutaremos:

SET serveroutput on
SET lines 100
DECLARE
   h1 NUMBER;
BEGIN
  -- Format: DBMS_DATAPUMP.ATTACH('[job_name]','[owner_name]');
   h1 := DBMS_DATAPUMP.ATTACH('SEXPORT_TABLA_1','SCOTT');
   DBMS_DATAPUMP.STOP_JOB (h1,1,0);
END;
/

Ejecutando la consulta que muestra los jobs de exports vemos que tenemos trabajos NOT RUNNING residuales, siempre podemos limpiar la tabla con el resultado de :

SELECT 'DROP TABLE '|| owner_name||'.'|| job_name ||';'
FROM dba_datapump_jobs
where STATE='NOT RUNNING';