domingo, 8 de marzo de 2015

Resolviendo ORA-01548: active rollback segment ‘_SYSSMU4_1254879796$’ después de la pérdida del datafile del tablespace UNDO

Todos los días somos alumnos de la vida. Algunos de los días se portan de mejor manera que otros, pero todos bien o mal, nos aportan conocimientos que luego podemos compartir con los demás.
Agradezco en este post, a todos los alumnos del día sábado por la tarde en Universidad CENFOTEC.
Durante las lecciones de este fin de semana en la clase de Oracle Database 11g Workshop II, tuvimos una situación peculiar en la realización de un laboratorio.

Durante la práctica utilizando una máquina virtual con Oracle Enterprise Linux 6.4 y Oracle Database 11gR2 11.2.0.4 borramos el datafile del tablespace de UNDO.

Necesario aclarar que la base de datos no estaba en modo ARCHIVELOG y no se contaba con un respaldo de la misma.

A pesar de que no estamos realizando ninguna operación que derivara la utilización del tablespace, algo creo información de "Undo". 

Al continuar con el procedimiento para reponer el tablespace de UNDO, creamos inicialmente un nuevo tablespace UNDO, lo seteamos a nivel del spfile y procedimos a reiniciar la base de datos.

SQL> create undo tablespace UNDOTBS2;

SQL> alter system set undo_tablespace=UNDOTBS2 scope=spfile;

SQL> startup force
ORACLE instance started.

Total System Global Area  801701888 bytes
Fixed Size                  2257520 bytes
Variable Size             276827536 bytes
Database Buffers          515899392 bytes
Redo Buffers                6717440 bytes
Database mounted.
Database opened.


Al intentar borrar el tablespace de UNDO, no fue posible. La instrucción devuelve un mensaje, de que existe un segmento de rollback activo.

SQL> drop tablespace undotbs1 including contents and datafiles; drop tablespace undotbs1 including contents and datafiles
*
ERROR at line 1: ORA-01548: active rollback segment ‘_SYSSMU4_1254879796$’ found, terminate dropping tablespace


Validando los segmentos activos en la vista dba_rollback_segs, encontramos varios segmentos de rollback, amarrados al tablespace UNDOTBS1, el cuál había sufrido la pérdida de su datafile. Los mismos indicaban en su estado, de que requerían "Recuperación!!"

SQL> select segment_name, tablespace_name, status from dba_rollback_segs where tablespace_name='UNDOTBS1';

SEGMENT_NAME         TABLESPACE_NAME    STATUS
-------------------- ------------------ ----------------
_SYSSMU4_1254879796$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU5_898567397$   UNDOTBS1          NEEDS RECOVERY
_SYSSMU6_1263032392$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU7_2070203016$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU8_517538920$   UNDOTBS1          NEEDS RECOVERY          
_SYSSMU9_1650507775$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU10_1197734989$ UNDOTBS1          NEEDS RECOVERY

Al intentar borrar los segmentos, recibimos como mensaje que no era permitido borrar un segmento de rollback en este tablespace.

SQL> drop rollback segment "_SYSSMU4_1254879796$";
drop rollback segment "_SYSSMU4_1254879796$"
*
ERROR at line 1:
ORA-30025: DROP segment '_SYSSMU4_1254879796$' (in undo tablespace) not allowed

Para solucionar este problema, es necesario echar mano del parámetro oculto _offline_rollback_segments y setear a nivel del spfile, los segmentos de rollback que son devueltos producto de la consulta del objeto dba_rollback_segs


SQL> select segment_name, tablespace_name, status from dba_rollback_segs where tablespace_name='UNDOTBS1';

SEGMENT_NAME         TABLESPACE_NAME    STATUS
-------------------- ------------------ ----------------
_SYSSMU4_1254879796$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU5_898567397$   UNDOTBS1          NEEDS RECOVERY
_SYSSMU6_1263032392$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU7_2070203016$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU8_517538920$   UNDOTBS1          NEEDS RECOVERY          
_SYSSMU9_1650507775$  UNDOTBS1          NEEDS RECOVERY
_SYSSMU10_1197734989$ UNDOTBS1          NEEDS RECOVERY

7 rows selected.

SQL> alter system set "_offline_rollback_segments" = '_SYSSMU4_1254879796$' , '_SYSSMU5_898567397$','_SYSSMU6_1263032392$', '_SYSSMU7_2070203016$','_SYSSMU8_517538920$','_SYSSMU9_1650507775$',
'_SYSSMU10_1197734989$' scope=spfile;

System altered.


Posteriormente configurados los segmentos de rollback, es necesario reiniciar la instancia de la base de datos para proceder a borrar manualmente los segmentos de rollback que no nos dejan borrar el tablespace de undo.

SQL> startup force
ORACLE instance started.

Total System Global Area  801701888 bytes
Fixed Size                  2257520 bytes
Variable Size             276827536 bytes
Database Buffers          515899392 bytes
Redo Buffers                6717440 bytes
Database mounted.
Database opened.


Creamos las sentencias requeridas para proceder con el borrado.

SQL> select 'drop rollback segment '||'"'||segment_name||'";' from  dba_rollback_segs 
where tablespace_name='UNDOTBS1';

'DROPROLLBACKSEGMENT'||'"'||SEGMENT_NAME||'";'
-------------------------------------------------------
drop rollback segment "_SYSSMU4_1254879796$";
drop rollback segment "_SYSSMU5_898567397$";
drop rollback segment "_SYSSMU6_1263032392$";
drop rollback segment "_SYSSMU7_2070203016$";
drop rollback segment "_SYSSMU8_517538920$";
drop rollback segment "_SYSSMU9_1650507775$";
drop rollback segment "_SYSSMU10_1197734989$";

7 rows selected.


Ejecutamos las sentencias como "/ as sysdba" en la base de datos.

SQL> drop rollback segment "_SYSSMU4_1254879796$";
drop rollback segment "_SYSSMU5_898567397$";
drop rollback segment "_SYSSMU6_1263032392$";
drop rollback segment "_SYSSMU7_2070203016$";
drop rollback segment "_SYSSMU8_517538920$";
drop rollback segment "_SYSSMU9_1650507775$";
drop rollback segment "_SYSSMU10_1197734989$";

Rollback segment dropped.

SQL>Rollback segment dropped.

SQL>Rollback segment dropped.

SQL>Rollback segment dropped.

SQL>Rollback segment dropped.

SQL>Rollback segment dropped.

SQL>Rollback segment dropped.


Validamos que no existan más segmentos creados en el tablespace que deseamos borrar.

SQL> select segment_name, tablespace_name, status from dba_rollback_segs where tablespace_name='UNDOTBS1';

no rows selected


Y finalmente, logramos nuestro objetivo. Borrar el tablespace de UNDO que ha sido sustituido.

SQL> drop tablespace undotbs1 including contents;

Tablespace dropped.

SQL>

1 comentario:

Te agradezco tus comentarios. Te esperamos de vuelta.