DBMS_DICTIONARY_CHECK en Oracle 19.22: Un reemplazo para el Healthcheck tradicional

Mi nombre es Carla y me defino como una apasionada de conocer, compartir ideas, divertirme y aprender todo lo relacionado con Oracle.
Alegre y creativa, con un alto grado de autoexigencia, que busca, incluso sin querer, una forma diferente de ver un mismo problema o solución. Defensora del trabajo en equipo en todas las facetas de la vida y de disfrutar todo lo que haces, siempre con humildad.
Actualmente cuento con más de 15 años de experiencia como administradora de Oracle, habiendo ocupado previamente posiciones como desarrolladora en la rama de Inteligencia de Negocios. Fue en ese momento que me di cuenta de que no quería centrarme en el desarrollo, sino participar en todas las capas que involucraban los datos, desde el despliegue de la base de datos hasta su explotación final.
Siempre estoy dispuesta a ayudar y compartir conocimientos. Creo firmemente que con la tecnología hay que divertirse y no verla como una competencia. La persona con la que tienes que ser el mejor es contigo mismo.
Con la versión 19.22 de Oracle Database, se ha incorporado de forma retroactiva el paquete DBMS_DICTIONARY_CHECK, proporcionando una forma más eficiente de validar la integridad del diccionario de datos.
Históricamente, esta tarea se realizaba mediante el script conocido como "hcheck.sql", que ejecutaba múltiples validaciones manuales sobre la estructura del diccionario.
En esta entrada, explicaré qué hace DBMS_DICTIONARY_CHECK, cómo se compara con los métodos anteriores y cuáles son sus beneficios.
¿Qué es DBMS_DICTIONARY_CHECK?
DBMS_DICTIONARY_CHECK es un paquete PL/SQL que permite verificar la consistencia del diccionario de datos de Oracle de una forma más automatizada y optimizada.
Su objetivo principal es detectar posibles corrupciones o inconsistencias en las estructuras internas de la base de datos antes de que se conviertan en problemas graves.
Funcionalidades principales:
Verifica la integridad de las estructuras clave del diccionario de datos.
Identifica objetos huérfanos o inconsistentes.
Reduce la necesidad de ejecutar múltiples scripts manuales para validaciones.
Ofrece un método más rápido y centralizado de chequeo.
Comparación con el Healthcheck tradicional
Antes de la introducción de DBMS_DICTIONARY_CHECK, los DBA solíamos ejecutar el script de verificación conocido como "hcheck.sql", los cuales:
Revisaba múltiples vistas del diccionario (DBA_SEGMENTS, DBA_OBJECTS, DBA_TABLES, etc.).
Identificaba segmentos no válidos o estructuras inconsistentes.
Requería ejecución manual y análisis de resultados.
La diferencia clave con DBMS_DICTIONARY_CHECK es que este nuevo paquete encapsula todas estas validaciones dentro de una ejecución más optimizada y directa.
Beneficios de DBMS_DICTIONARY_CHECK
Automatización y facilidad de uso: Se puede ejecutar como un procedimiento almacenado.
Eficiencia mejorada: Optimiza las consultas internas para reducir el impacto en el rendimiento.
Menos margen de error: Reduce la posibilidad de omitir chequeos importantes.
Compatibilidad con versiones anteriores: Al haber sido incorporado en la versión 19.22, se puede usar en entornos que no han migrado aún a versiones más recientes.
Prevención temprana de problemas: Permite detectar inconsistencias antes de que generen errores críticos en la base de datos.
Conclusión
La incorporación de DBMS_DICTIONARY_CHECK en Oracle 19.22 representa un avance significativo en la administración de la integridad del diccionario de datos.
Su uso reemplaza de manera efectiva hcheck ofreciendo un enfoque más rápido y centralizado.
Ejemplo ejecución:
SYS@CDB$ROOT> set serveroutput on size unlimited
SYS@CDB$ROOT> execute dbms_dictionary_check.full
dbms_dictionary_check on 07-MAR-2025 15:11:23
----------------------------------------------
Catalog Version 19.0.0.0.0 (1900000000)
db_name: CDBXXX
Is CDB?: YES CON_ID: 1 Container: CDB$ROOT
Trace File: /u01/app/oracle/diag/rdbms/cdbxxx/cdbxxx1/trace/cdbxxxx1_ora_3844489_DICTCHECK.trc
Catalog Fixed
Procedure Name Version Vs Release Timestamp Result
------------------------------ ... ---------- -- ---------- -------------- ------
.- OIDOnObjCol ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- LobNotInObj ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- SourceNotInObj ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- OversizedFiles ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- PoorDefaultStorage ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- PoorStorage ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- TabPartCountMismatch ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- TabComPartObj ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- Mview ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidDir ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- DuplicateDataobj ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ObjSyn ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ObjSeq ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- UndoSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- IndexSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- IndexPartitionSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- IndexSubPartitionSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- TableSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- TablePartitionSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- TableSubPartitionSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- PartCol ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- IndPartObj ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- DuplicateBlockUse ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- FetUet ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- Uet0Check ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- SeglessUET ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidInd ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidTab ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- IcolDepCnt ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ObjIndDobj ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- TrgAfterUpgrade ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ObjType0 ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidOwner ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- StmtAuditOnCommit ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- PublicObjects ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- SegFreelist ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidDepends ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- CheckDual ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ObjectNames ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- CboHiLo ... 1900000000 <= 1902000000 03/07 15:11:23 PASS
.- ChkIotTs ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- NoSegmentIndex ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- NextObject ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- DroppedROTS ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- FilBlkZero ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- DbmsSchemaCopy ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- IdnseqObj ... 1900000000 > 1201000000 03/07 15:11:23 PASS
.- IdnseqSeq ... 1900000000 > 1201000000 03/07 15:11:23 PASS
.- ObjError ... 1900000000 > 1102000000 03/07 15:11:23 PASS
.- ObjNotLob ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- MaxControlfSeq ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- SegNotInDeferredStg ... 1900000000 > 1102000000 03/07 15:11:23 PASS
.- SystemNotRfile1 ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- DictOwnNonDefaultSYSTEM ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ValidateTrigger ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- ObjNotTrigger ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- InvalidTSMaxSCN ... 1900000000 > 1202000000 03/07 15:11:23 PASS
.- OBJRecycleBin ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
.- LobSeg ... 1900000000 <= *All Rel* 03/07 15:11:23 PASS
---------------------------------------
07-MAR-2025 15:11:23 Elapsed: 0 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /u01/app/oracle/diag/rdbms/cdbxxx/cdbxxx1/trace/cdbxxx1_ora_3844489_DICTCHECK.trc
Procedimiento PL/SQL terminado correctamente.
Nos centramos en validaciones críticas:
SYS@CDB$ROOT> execute dbms_dictionary_check.critical
dbms_dictionary_check on 07-MAR-2025 15:13:04
----------------------------------------------
Catalog Version 19.0.0.0.0 (1900000000)
db_name: CDBXXX
Is CDB?: YES CON_ID: 1 Container: CDB$ROOT
Trace File: /u01/app/oracle/diag/rdbms/cdbxxx/cdbxxx1/trace/cdbxxx1_ora_3844489_DICTCHECK.trc
Catalog Fixed
Procedure Name Version Vs Release Timestamp Result
------------------------------ ... ---------- -- ---------- -------------- ------
.- UndoSeg ... 1900000000 <= *All Rel* 03/07 15:13:04 PASS
.- MaxControlfSeq ... 1900000000 <= *All Rel* 03/07 15:13:04 PASS
.- InvalidTSMaxSCN ... 1900000000 > 1202000000 03/07 15:13:04 PASS
---------------------------------------
07-MAR-2025 15:13:04 Elapsed: 0 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /u01/app/oracle/diag/rdbms/cdbxxx/cdbxxx1/trace/cdbxxx1_ora_3844489_DICTCHECK.trc
Procedimiento PL/SQL terminado correctamente.
Te imaginas que se puede ejecutar con opción de reparación?
EXECUTE dbms_dictionary_check.ValidateSeg(repair=>TRUE)
Esto eliminaría los registros inconsistentes y restauraría la integridad del diccionario.



