2/9/10

La papelera de reciclaje de Oracle10g: Recycle Bin

A partir de Oracle10g se incorpora esta nueva funcionalidad, denominada FLASHBACK DROP, que se viene a unir a las demás características que conforman el capítulo de las funcionalidades FLASHBACK. La idea es la misma que tienen algunos sistemas operativos con su papelera de reciclaje, es decir, disponer de una ubicación donde colocar los objetos borrados con el fin de poder recuperarlos después. Por supuesto, todo esto se hace de forma transparente para el usuario.

1. Finalidad
Cuando un usuario lanza la orden DROP sobre una tabla, en realidad, lo que hace Oracle es renombrar ese objeto y todas sus dependencias, tales como triggers, índices, constraints etc. El nombre que recibe el objeto es generado automáticamente por Oracle pero siempre está prefijado por BIN$. Como sólo se produce un renombrado, los objetos siguen existiendo y ocupando espacio sus correspondientes tablespaces. El objeto sólo se borra definitavemente si el usuario o el administrador usan el comando PURGE o el espacioocupado por ese objeto es necesario para acomodar una nueva extensión de un objeto vivo (por esto último, se dice que FLASHBACK DROP no es intrusivo ya que si el espacio ocupado por la papelera es necesario se libera automáticamente).Por el contrario, cuando se borra un tablespace sus objetos no son pasados a la papelera sino que son borrados definitivamente, incluyendo los objetos que estén en la papelera de ese tablespace. Lo mismo ocurre cuando se borra un usuario con opción CASCADE.
2. Estructura
La vista RECYCLEBIN es un sinónimo que apunta a la vista USER_RECYCLEBIN que su vez apunta a la tabla SYS.RECYCLEBIN$. Por tanto, es indiferente consultar RECYCLEBIN o USER_RECYCLEBIN. La estructura de esta vista es:
Nombre              ¿Nulo?            Tipo
------------------- ----------------- ------------
OBJECT_NAME         NOT NULL          VARCHAR2(30)
ORIGINAL_NAME                         VARCHAR2(32)
OPERATION                             VARCHAR2(9)
TYPE                                  VARCHAR2(25)
TS_NAME                               VARCHAR2(30)
CREATETIME                            VARCHAR2(19)
DROPTIME                              VARCHAR2(19)
DROPSCN                               NUMBER
PARTITION_NAME                        VARCHAR2(32)
CAN_UNDROP                            VARCHAR2(3)
CAN_PURGE                             VARCHAR2(3)
RELATED             NOT NULL          NUMBER
BASE_OBJECT         NOT NULL          NUMBER
PURGE_OBJECT        NOT NULL          NUMBER
SPACE                                 NUMBER
Cada vez que un objeto es borrado con el comando DROP se crea una entrada nueva en esta vista que tiene el nombre nuevo dado al objeto, prefijado por BIN$, su nombre original, el tablespace en el que reside, la fecha y hora de eliminación, el espacio que ocupa, etc.

3. Ver el contenido de las tablas de la papelera
Las tablas borradas que residen en la papelera pueden ser consultados con las mismas restricciones que tenían antes de ser borrados. Para consultarlos hay que usar el nombre nuevo que le asigna Oracle entrecomillándolo.
Esta tablas de la papelera son de solo lectura. Si se intenta un transacción DML se obtiene el siguiente error: ORA-38301: no se puede realizar DDL/DML en objetos de la papelera de reciclaje.

4. Restaurar un objeto borrado
Al restaurar un objeto también se restauran sus objetos dependientes, pero estos conservan los nombres que tenían en la papelera. Se puede conseguir de varias formas:
  1. Haciendo un CREATE TABLE nombre_tabla... AS SELECT * FROM nombre_tabla_borrada.
  2. Creando la tabla manualmente mediante CREATE TABLE y después rellenarla usando INSERT INTO nombre_tabla AS SELECT * FROM nombre_tabla_borrada.
  3. Usando FLASHBACK TABLE nombre_tabla TO BEFORE DROP [RENAME TO nuevo_nombre_tabla]. En este caso el nombre_tabla puede ser el nombre original de la tabla asignado por Oracle al meterla en la papelera. IMPORTANTE: si existe más de una tabla en la papelera con el mismo nombre que la tabla original, Oracle restauraría la borrada más o el recientemente. Por esta razón, es más seguro usar el nombre generado por Oracle. Por último, con la cláusula RENAME TO se puede indicar el nuevo nombre que tendrá la tabla después de ser recuperada.
5. Vaciar papelera
Como ya se ha indicado, la eliminación de los objetos residentes en la papelera se puede hacer manualmente a través del comando PURGE. Con este comando sólo se pueden borrar los objetos del usuario que lanza la orden, salvo que se disponga de permiso SYSDBA o DROP ANY. Las variantes que existen son:
  • PURGE TABLE nombre_tabla: Elimina la tabla indicada de la papelera. El nombre de la tabla puede ser el nombre original o el renombrado.
  • PURGE INDEX nombre_índice: Elimina el índice indicado de la papelera. El nombre del índice es el nombre original y no el renombrado.
  • PURGE RECYCLEBIN: Elimina todos los objetos (del usuario que lanza la orden) de la papelera.
  • PURGE DBA_RECYCLEBIN: Elimina todos los objetos (de todos los usuarios) de la papelera. Solo un SYSDBA puede lanzar este comando.
  • PURGE TABLESPACE nombre_tablespace: Elimina todos los objetos (del usuario) de la papelera que residan en el tablespace indicado.
  • PURGE TABLESPACE nombre_tablespace USER nombre_usuario: Elimina todos los objetos de la papelera que residan en el tablespace indicado y pertenezcan el usuario indicado.
6. Eliminar sin pasar por la papelera de reciclaje
Sí. Existen dos modos para evitar que el objeto borrado pase a la papelera:

  1. A través de un parámetro del INIT.ORA. En Oracle10g R1 es _RECYCLEBIN, un parámetro oculto porque empieza por el carácter subrayado "_", que por omisión está a TRUE. Asignándole FALSE hacemos que Oracle10g no use la papelera y elimine el objeto definitivamente, como en anteriores versiones. En Oracle10g R2 se usa el parámetro RECYCLEBIN, éste ya no oculto, cuyos valores son ON y OFF siendo ON el valor por omisión. Éste parámetro es dinámico por lo que se puede cambiar para la sesión o para la Instancia.
  2. Usando la cláusula PURGE del comando DROP. Con esta opción conseguimos el mismo efecto pero hay que indicarlo en cada comando DROP que usemos.
7. Ejemplo completo en Oracle10g Release 2
7.1 Creamos una tabla cualquiera llama T1
SQL> create table t1 (c number(1)) tablespace users;
Tabla creada.
7.2 Comprobamos si existe alguna tabla borrada en la papelera
SQL> select * from recyclebin; -- o SHOW RECYCLEBIN
ninguna fila seleccionada.
7.3 Borramos la tabla T1
SQL> drop table t1;
Tabla borrada.
7.4 Comprobamos que la tabla está ahora en la papelera
SQL> select object_name, original_name from recyclebin;
OBJECT_NAME                    ORIGINAL_NAME
------------------------------ ---------------
BIN$ACEfotX6TRqgiRnY6LN6nQ==$0 T1
7.5 Volvemos a crear de nuevo la tabla T1
Comprobando que la borró de verdad (si no la hubiera borrado no nos dejaría volver a crearla):
SQL> create table t1 (c number(1)) tablespace users;
Tabla creada.
7.6 La volvemos a borrar
SQL> drop table t1;
Tabla borrada.
7.7 Comprobamos que ahora están las dos tablas en la papelera
SQL> select object_name, original_name from recyclebin;

SQL> select object_name, original_name from recyclebin;
OBJECT_NAME                    ORIGINAL_NAME
------------------------------ ---------------
BIN$ACEfotX6TRqgiRnY6LN6nQ==$0 T1
BIN$ZdHqVQ+nS0OJsW83y8BEoQ==$0 T1
7.8 Intentamos acceder a alguna de las tablas borradas en selección e inserción
SQL> select * from "BIN$ZdHqVQ+nS0OJsW83y8BEoQ==$0";
ninguna fila seleccionada

SQL> insert into "BIN$ZdHqVQ+nS0OJsW83y8BEoQ==$0" values (1);
insert into "BIN$ZdHqVQ+nS0OJsW83y8BEoQ==$0" values (1)* ERROR en línea 1:
ORA-38301: no se puede realizar DDL/DML en objetos de la papelera de reciclaje.
7.9 Eliminamos la tabla T1 de la papelera
Como hay dos borra la T1 más antigua.
SQL> purge table t1;
Tabla depurada.

SQL> select object_name, original_name from recyclebin;
OBJECT_NAME                    ORIGINAL_NAME
------------------------------ -------------
BIN$ZdHqVQ+nS0OJsW83y8BEoQ==$0 T1
7.10 Volvemos a crear la tabla T1
SQL> create table t1 (c number(1)) tablespace users;
Tabla creada.
7.11 Ahora la borramos sin dejarla ir a la papelera de reciclaje
SQL> drop table t1 PURGE;
Tabla creada.

SQL> select object_name, original_name from recyclebin;
OBJECT_NAME                    ORIGINAL_NAME
------------------------------ -------------
BIN$ZdHqVQ+nS0OJsW83y8BEoQ==$0 T1
7.12 Por último, restauramos la tabla T1 desde la papelera de reciclaje
Si existiese ya una tabla con el nombre T1 obtendríamos el error ORA-38312: el nombre original lo ha utilizado un objeto existente. En este caso usaríamos la cláusula vista anteriormente RENAME TO nuevo_nombre:
SQL> flashback table T1 to before drop;
Flashback terminado.

SQL> select object_name, original_name from recyclebin;
ninguna fila seleccionada
8. Fuente
Juan Lorenzo Arellano Oracle DBA Infor Consult Soluciones www.inforconsult.es

No hay comentarios:

Publicar un comentario