ORA-01578: ORACLE data block corrupted (file # 7, block # 34982)
ORA-01110: data file 7: '+DATA/SISTEMA_01/DATAFILE/imagen_lob.424.1032123411'
ORA-26040: Data block was loaded using the NOLOGGING option
1) Significa que los datos ya estaban dañados, principalmente debido a corrupciones lógicas,
no es probable que sea una falla del hardware. Pero la pregunta clave es:
¿Podemos recuperar los datos dañados?
2)
Por defecto, las tablas e indices se crean en logging, a menos que se aplique la clausula durante la creación de la tabla o el tablespace.Este parametro es completamente ignorado si la base de datos está configurada con FORCE LOGGING.
LOGGING:
Cada
vez que la base ejecuta un DML o un DDL o un COMMIT, Oracle escribe en el redo log buffer, que despues es enviado a los redo log files, convirtiendoce en los archive log files (si la
base esta en archivelog mode).
Cuando
la transacción es realizada permanente con un COMMIT, se crea un nuevo registro
en el redolog buffer y asigna un nuevo SCN al cambio.
Este es el
mecanismo de proteccion que tiene la base para que en caso de tener que
hacer un recover, cuente con toda la información a ser aplicada a los datafiles
almacenada desde los redolog o archive log.
NOLOGGING:
Solo afecta a los direct-path load que se hagan a la base de datos. No afecta a los DML convencionales como INSERT, UPDATE, DELETE.
como validar los bloques corruptos en un datafile:
select * from dba_extents where file_id = 7 and 34982 between block_id and block_id + blocks - 1;
Solucion:
1) crear tabla de validacion registros malos
CREATE TABLE esquema.corruptos_blobs
(corrupt_rowid rowid, err_num number)
TABLESPACE REPARA_TABLA_IMAGEN;
2) procedimiento que valida los registos con problemas,
-- FOTO &&blob_columna
-- ESQUEMA &tabla_owner
-- FOTOS &tabla_con_blob
declare
error_1578 exception;
error_1555 exception;
error_22922 exception;
pragma exception_init(error_1578,-1578);
pragma exception_init(error_1555,-1555);
pragma exception_init(error_22922,-22922);
num number;
begin
for cursor_lob in (select rowid r, &&
from &blob_columna
..&tabla_owner
) looptabla_con_blob
begin
num := dbms_lob.instr (cursor_lob.&&
, hextoraw ('889911')) ;blob_columna
exception
when error_1578 then
insert into desarrollo.
values (cursor_lob.r, 1578);corruptos_blobs
commit;
when error_1555 then
insert into desarrollo.
values (cursor_lob.r, 1555);corruptos_blobs
commit;
when error_22922 then
insert into desarrollo.
values (cursor_lob.r, 22922);corruptos_blobs
commit;
end;
end loop;
end;
3) marcar los registros con problemas
update ESQUEMA.FOTOS
set foto = empty_blob()
where rowid in (select corrupt_rowid from equema.
);corruptos_blobs
commit;
4) realizar exportacion de los registros
[oracle@boston]$ vi exparameter.par
directory=mydirectorio
dumpfile=tbl_fotos.dmp
logfile=tbl_fotos.log
tables=totos
query=foto:"where rowid not in (select corrupt_rowid from esquema.
)"corruptos_blobs
expdp \"usuario/clave\" parfile=exparameter.par
exp \"usuario/clave\" TABLES=fotos query=\"where rowid not in \(select corrupt_rowid from esquema.
\)\" FILE=exp_tabla.dmp log=exp_tabla.logcorruptos_blobs