Como manejar ficheros tar.gz

Supongamos que tenemos un directorio en un entorno *nix del que queremos hacer una copia rápida de seguridad. Lo habitual es preparar un tar y una vez empaquetado se comprime con un gzip.

Para comprimir el directorio en una sola instrucción basta con hacer.

tar czf nombreFichero.tar.gz carpetaAComprimir

Para descomprimir el directorio

tar -zxvf /path/a/la/carpeta/nombreFichero.tar.gz

Para ver un listado de todos los ficheros del tar

gunzip -c nombreFichero.tar.gz | tar -tvf -

Para recuperar un solo fichero del tar.gz

gunzip -c nombreFichero.tar.gz | tar -xvf - path/dentro/del/fichero/index.html

En un único paso, sencillo ¿no?

Reconstruir un UNDO

Los tablespaces de UNDO son muy faciles de recrear. Vayamos paso a paso.

  • Nos conectamos como SYS. 
  • Consultamos en la tabla parameters los valores del undo:

     SQL> select name, value from v$parameter where name like '%undo%';

    NAME                    VALUE
    ----------------------- -----------
    undo_management         AUTO
    undo_tablespace         UNDOTBS
     

  • Creamos un tablespace de undo para reemplazar al anterior:

    create undo tablespace UNDOTBS2 datafile /u01/oradata/SID/UNDOTBS2_01.dbf' size 1000m reuse;
     

  • Convertimos este UNDO en el de referencia

    alter system set undo_tablespace=UNDOTBS2;
     

  • Ya podemos eliminar el UNDO original

    drop tablespace UNDOTBS including contents;

With as Select

Recientemente he encontrado una ayuda para escribir consultas complejas, o lo que es mejor, escribir menos para hacer lo mismo.

La nueva estructura es WITH AS SELECT y he aquí un ejemplo:

With dia As
(Select TRUNC (SYSDATE, 'D') d
From DUAL)
Select TO_CHAR (d, 'D'), TO_CHAR (d, 'DAY'), TO_CHAR (d)
From dia;

(Esta consulta te permite ver de un plumazo cual es el primer día de la semana en una bbdd cuya configuración desconoces y no sabes nada de los parametros NLS)

El WITH nos permite definir en la parte superior tantas subconsultas como necesitemos para simplificar el código y utilizar sus alias libremente en la consulta principal. Ideal para quien no le gusta escribir dos veces la misma cosa.

Respecto al rendimiento: Oracle se esfuerza por optimizarla reescribiendola como una vista en linea o una tabla temporal. Es decir, tan bueno o malo como el rendimiento del original.

Otro ejemplo típico viene en los manuales de oracle:

WITH
dept_costs AS (
SELECT department_name, SUM(salary) dept_total
FROM employees e, departments d
WHERE e.department_id = d.department_id
GROUP BY department_name),
avg_cost AS (
SELECT SUM(dept_total)/COUNT(*) avg
FROM dept_costs)
SELECT * FROM dept_costs
WHERE dept_total >
(SELECT avg FROM avg_cost)
ORDER BY department_name;

DEPARTMENT_NAME DEPT_TOTAL
------------------------------ ----------
Sales 313800
Shipping 156400

War is peace, Freedom is slavery, Ignorance is strength

A veces, como San Pablo, tienes un fogonazo de verdad y todo cobra sentido.

Hay que reescribir los memes, por que la ignorancia es fortaleza. Cuando tenemos un enemigo claramente identificado todo es mucho más sencillo, especialmente para los que detentan el poder. Lamentablemente si nuestra libertad se limita a elegir entre una estantería del supermercado u otra, la libertad no tiene sentido.

El Gran Hermano no es programa de televisión, es el mundo real.

Matando sesiones desde el sistema operativo

Como comenté en un post anterior, la mejor manera de matar una sesión de Oracle es desde dentro del servicio.

ALTER SYSTEM KILL SESSION 'sid,serial#' [IMMEDIATE];

Al recibir este Alter, la sesión pasa a modo KILLED, estado en el que intenta liberar los recursos empleados aunque, lamentablemente, no siempre lo consigue.

Para rematar una sesión marcada como KILLED que realmente no muere con el paso del tiempo hay que operar desde el sistema operativo.

El primer paso es identificar el proceso del sistema operativo conociendo el SID:

select p.spid, s.sid, s.serial#, s.username
from v$session s, v$process p
where p.addr = s.paddr and
s.sid= &SID;

La estructura de los procesos Oracle en Windows y Unix es un poco distinta, por ello para Unix se ejecutará la instrucción:

KILL -9 {spid}

Y desde windows:

orakill {S*I*D} {spid}

IMPORTANTE: este ultimo {S*I*D} es el identificador de la bbdd, no de la sesión.

SQL: Minutos entre dos fechas

Es muy rápido averiguar los minutos que separan dos fechas en Oracle.

Como todos sabemos el tipo DATE en Oracle se almacena internamente en números enteros. La unidad es el día, luego para conocer el día de mañana “a la misma hora” basta con sumar (sysdate + 1).

Si tenemos dos date A y B, siendo A>B, los minutos aproximados que las separan se calcula como:

Select ROUND ((A - B) * 24 * 60)
From DUAL;