Oracle Hcheck(Health Check)是Oracle数据库内置的健康监测工具,自动化检查数据库的核心问题,包括数据字典一致性、性能瓶颈、空间使用及安全隐患。本质是数据字典的CT扫描仪,其核心价值在于将“字典逻辑错误”这类灰色地带的故障扼杀在初始阶段。
Hcheck专注修复元数据逻辑层的隐蔽错误(非物理文件损坏),这类问题虽然不会立即导致崩溃,但会逐步侵蚀稳定性。通过定期执行CRITICAL模式(轻量级检查),可提前拦截大部分都字典级隐患,尤其适用于频繁DDL变更的开发测试环境,预防从而避免问题蔓延至生产。
但HCHECK无法进行物理损坏(如磁盘坏道)这样的底层,同业也无法检测漏洞和补丁。
一、hcheck的主要功能和特点
主要功能:
- 数据字典检查:通过内置规则(如DBMS_HCHECK或DBMS_DICTIONARY_CHECK包)
扫描数据字典的完整性,检测如对象缺失、索引孤立、表分区异常等问题
- 检查模式:支持FULL(全面检查)和CRITICAL(仅关键检查),后者速度更快
- 修复能力:通过Repair=TRUE参数自动修复部分问题(如修复元数据不一致)
- 多维度监控:
- 性能:采集动态视图(如V$SYSSTAT)分析CPU、I/O、内存资源瓶颈
- 空间:监控表空间、数据文件、索引的存储状态,预防空间不足风险
- 安全:识别弱密码、未授权访问等漏洞
- 自动化报告:生成分级报告(CRITICAL/FAIL/WARN/PASS),明确优先级并提供解决方案建议
核心特点:
- 轻量化与集成化:作为数据库原生组件(取代早期脚本hcheck.sql),无需外部依赖,可直接通过PL/SQL调用
- 修复一体化:支持“检测-修复”闭环操作,简化DBA维护流程
- 多环境适配:适用于CDB/PDB容器化架构,兼容Oracle 23ai及以上版本(23ai中更名为DBMS_DICTIONARY_CHECK)
二、演进历程
1. 上古时期:hcheck.sql (文档 ID 136697.1)
- 起源:早期 Oracle 版本(如 10g/11g)缺乏内置检查工具,用户需手动下载脚本 hcheck.sql。
- 动作:
- 需从 My Oracle Support 单独下载
- 无修复功能,仅能检测问题
- 执行过程需手工解析日志
- 典型输出:
SQL> @hcheck
HCheck Version 04AUG23
Procedure Name Result
----------------------- ------
LobNotInObj PASS
OrphanedIndex FAIL -- 需人工干预
2. 23ai:DBMS_DICTIONARY_CHECK
- 革新:首次将检查能力封装为内置包,支持 CDB/PDB 架构。
- 核心特性:
- 提供 FULL(全量检查)和 CRITICAL(关键项检查)两种模式
- 支持 REPAIR=TRUE 参数自动修复问题
- 结果分级:CRITICAL > FAIL > WARN > PASS
- 示例代码(23ai发版会有改变):
-- 关键检查(PDB 环境)
EXEC DBMS_DICTIONARY_CHECK.CRITICAL;-- 全量检查并修复
EXEC DBMS_DICTIONARY_CHECK.FULL(repair=>TRUE);
3. 新的演进:DBMS_HCHECK (Oracle 23ai正式发版之后)
- 命名统一:包名标准化为 DBMS_HCHECK,功能继承并增强。
- 核心优化:
- 完全替代 hcheck.sql,无需外部脚本
- 深度集成到数据库内核,检查效率提升 50%+
- 输出标准化,日志自动写入 trace 文件
三、核心功能解析
健康检查等级
检查类型 | 执行命令 | 耗时 | 适用场景 |
CRITICAL | DBMS_HCHECK.CRITICAL; | 秒级 | 紧急运维、升级后快速验证 |
FULL | DBMS_HCHECK.FULL; | 分钟级 | 周期性深度健康检查 |
FULL (修复模式) | DBMS_HCHECK.FULL(repair=>TRUE); | 分钟级 | 发现严重问题后自动修复 |
四、全版本操作指南
1. Oracle 11g/12c/19c:使用 hcheck.sql
-- 下载脚本后执行(需SYSDBA)
[root@rac11 ~]# find / -name hcheck.sql
/opt/oracle.ahf/orachk/.cgrep/hcheck.sql
/opt/oracle.ahf/tfa/resources/sql/hcheck.sqlSPOOL hcheck.log
@/opt/oracle.ahf/tfa/resources/sql/hcheck.sql
SPOOL OFF
--
SQL> SPOOL hcheck.log
SQL> @/opt/oracle.ahf/tfa/resources/sql/hcheck.sqlSession altered.HCheck Version 04AUG23 on 20-JUN-2025 18:51:56
----------------------------------------------
Catalog Version 19.0.0.0.0 (1900000000)
db_name: PRODCDB
Is CDB?: YES CON_ID: 1 Container: CDB$ROOTCatalog Fixed
Procedure Name Version Vs Release Timestamp
Result
------------------------------ ... ---------- -- ---------- --------------
------
.- LobNotInObj ... 1900000000 <= *All Rel* 06/20 18:51:56 PASS
…………
.- BadSegFreelist ... 1900000000 <= *All Rel* 06/20 18:51:57 PASS
.- BadDepends ... 1900000000 <= *All Rel* 06/20 18:51:57 WARNHCKW-0016: Dependency$ p_timestamp mismatch for VALID objects (Doc ID
1361045.1)
[W] - P_OBJ#=66997 D_OBJ#=67053
……………………
[W] - P_OBJ#=67044 D_OBJ#=67100
[W] - P_OBJ#=67045 D_OBJ#=67101
[W] - P_OBJ#=67048 D_OBJ#=67104
[W] - P_OBJ#=67049 D_OBJ#=67105
[W] - P_OBJ#=67050 D_OBJ#=67106
[W] - P_OBJ#=67051 D_OBJ#=67107.- CheckDual ... 1900000000 <= *All Rel* 06/20 18:51:57 PASS
.- ObjectNames ... 1900000000 <= *All Rel* 06/20 18:51:57 PASS
…………
.- SystemNotRfile1 ... 1900000000 > 902000000 06/20 18:51:58 PASS
.- DictOwnNonDefaultSYSTEM ... 1900000000 <= *All Rel* 06/20 18:51:58 PASS
.- OrphanTrigger ... 1900000000 <= *All Rel* 06/20 18:51:58 PASS
.- ObjNotTrigger ... 1900000000 <= *All Rel* 06/20 18:51:58 PASS
---------------------------------------
20-JUN-2025 18:51:58 Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 40 warning(s)
Contact Oracle Support with the output and trace file
to check if the above needs attention or notPL/SQL procedure successfully completed.Statement processed.Complete output is in trace file:
/u01/app/oracle/diag/rdbms/prodcdb/prodcdb1/trace/prodcdb1_ora_276568_HCHECK.trcSession altered.
SQL> SPOOL OFF-- 结果分析 grep "FAIL" hcheck.log 提取问题项
tail -f -n 300 /u01/app/oracle/diag/rdbms/prodcdb/prodcdb1/trace/prodcdb1_ora_276568_HCHECK.trc
……………………
.- OrphanTrigger ... 1900000000 <= *All Rel* 06/20 18:51:58
PASS
.- ObjNotTrigger ... 1900000000 <= *All Rel* 06/20 18:51:58
PASS
---------------------------------------
20-JUN-2025 18:51:58 Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 40 warning(s)Contact Oracle Support with the output and trace file
to check if the above needs attention or not*** 2025-06-20T18:51:58.059112+08:00 (CDB$ROOT(1))
Processing Oradebug command 'setmypid'*** 2025-06-20T18:51:58.059145+08:00 (CDB$ROOT(1))
Oradebug command 'setmypid' console output: <none>*** 2025-06-20T18:51:58.059203+08:00 (CDB$ROOT(1))
Processing Oradebug command 'tracefile_name'*** 2025-06-20T18:51:58.059214+08:00 (CDB$ROOT(1))
Oradebug command 'tracefile_name' console output:
/u01/app/oracle/diag/rdbms/prodcdb/prodcdb1/trace/prodcdb1_ora_276568_HCHECK.trc
2. Oracle 23.3ai:Oracle 23ai free-版本23.8.0.25.04-DBMS_DICTIONARY_CHECK.FULL();
-- 23ai内置DBMS_HCHECK(现在依然是DBMS_DICTIONARY_CHECK),数据字典健康检查(替代传统hcheck.sql)
-- 验证数据库版本
SELECT BANNER_FULL FROM V$VERSION;
--
BANNER_FULL
__________________________________________________________________________________
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04-- 检查 DBMS_HCHECK 可用性 ,查询可用的数据字典检查包
SELECT OBJECT_NAME
FROM ALL_OBJECTS
WHERE OWNER = 'SYS'
AND OBJECT_NAME LIKE 'DBMS_%CHECK%';
--
OBJECT_NAME
_______________________________
DBMS_DICTIONARY_CHECK
DBMS_DICTIONARY_CHECK
DBMS_DICTIONARY_CHECK_LIB
DBMS_EXTENDED_TTS_CHECKS
DBMS_PDB_CHECK_LOCKDOWN
DBMS_EXTENDED_TTS_CHECKS
DBMS_EXTENDED_TTS_CHECKS_LIB
--
7 rows selected.
Elapsed: 00:00:00.192
-- 全面检查
SET SERVEROUTPUT ON SIZE UNLIMITED
BEGINSYS.DBMS_DICTIONARY_CHECK.FULL();
END;
/
--
SYS@CDB$ROOT> BEGIN2 SYS.DBMS_DICTIONARY_CHECK.FULL();3 END;4* /
dbms_dictionary_check on 20-JUN-2025 17:48:37
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 1 Container: CDB$ROOT
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_128711_DICTCHECK.trcCatalog Fixed
Procedure Name Version Vs Release Timestamp Result
------------------------------ ... ---------- -- ---------- -------------- ------
.- OIDOnObjCol ... 2300000000 <= *All Rel* 06/20 17:48:37 PASS
.- LobNotInObj ... 2300000000 <= *All Rel* 06/20 17:48:37 PASS
…………………………
- ValidateTrigger ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- ObjNotTrigger ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- InvalidTSMaxSCN ... 2300000000 > 1202000000 06/20 17:48:39 PASS
.- OBJRecycleBin ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- LobSeg ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- ObjLogicalConstraints ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- SysSequences ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- ValidateFile ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
.- ValidateObjStub ... 2300000000 <= *All Rel* 06/20 17:48:39 PASS
---------------------------------------
20-JUN-2025 17:48:39 Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_128711_DICTCHECK.trc
PL/SQL procedure successfully completed.
Elapsed: 00:00:02.215
-- 关键检查
SET SERVEROUTPUT ON SIZE UNLIMITED
BEGINSYS.DBMS_DICTIONARY_CHECK.CRITICAL();
END;
/
--
SYS@CDB$ROOT> SET SERVEROUTPUT ON SIZE UNLIMITED
SYS@CDB$ROOT> BEGIN2 SYS.DBMS_DICTIONARY_CHECK.CRITICAL();3 END;4* /
dbms_dictionary_check on 20-JUN-2025 17:56:25
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_128711_DICTCHECK.trcCatalog Fixed
Procedure Name Version Vs Release Timestamp Result
------------------------------ ... ---------- -- ---------- -------------- ------
.- UndoSeg ... 2300000000 <= *All Rel* 06/20 17:56:25 PASS
.- MaxControlfSeq ... 2300000000 <= *All Rel* 06/20 17:56:25 PASS
.- InvalidTSMaxSCN ... 2300000000 > 1202000000 06/20 17:56:25 PASS
.- SysSequences ... 2300000000 <= *All Rel* 06/20 17:56:25 PASS
---------------------------------------
20-JUN-2025 17:56:25 Elapsed: 0 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_128711_DICTCHECK.trc
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.056
--检查后修复
SET SERVEROUTPUT ON SIZE UNLIMITED
BEGINSYS.DBMS_DICTIONARY_CHECK.FULL(repair => TRUE);
END;
/
SYS@CDB$ROOT> SET SERVEROUTPUT ON SIZE UNLIMITED
SYS@CDB$ROOT> BEGIN2 SYS.DBMS_DICTIONARY_CHECK.FULL(repair => TRUE);3 END;4* /
dbms_dictionary_check on 20-JUN-2025 17:57:36
----------------------------------------------
Catalog Version 23.0.0.0.0 (2300000000)
db_name: FREE
Is CDB?: YES CON_ID: 3 Container: FREEPDB1
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_128711_DICTCHECK.trcCatalog Fixed
Procedure Name Version Vs Release Timestamp Result
------------------------------ ... ---------- -- ---------- -------------- ------
.- OIDOnObjCol ... 2300000000 <= *All Rel* 06/20 17:57:36 PASS
.- LobNotInObj ... 2300000000 <= *All Rel* 06/20 17:57:36 PASS
.- SourceNotInObj ... 2300000000 <= *All Rel* 06/20 17:57:36 PASS
^^^
--.- ValidateFile ... 2300000000 <= *All Rel* 06/20 17:57:38 PASS
.- ValidateObjStub ... 2300000000 <= *All Rel* 06/20 17:57:38 PASS
---------------------------------------
20-JUN-2025 17:57:38 Elapsed: 2 secs
---------------------------------------
Found 0 potential problem(s) and 0 warning(s)
Trace File: /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_128711_DICTCHECK.trc
PL/SQL procedure successfully completed.
Elapsed: 00:00:02.294
SYS@CDB$ROOT>
--仅诊断
BEGINSYS.DBMS_DICTIONARY_CHECK.FULL(repair => FALSE);
END;
/
3、核心功能说明
检查级别:
- - CRITICAL:关键检查
- - FULL:全面检查
修复模式:
- - repair => TRUE:自动修复问题
- - repair => FALSE:仅诊断(默认)
四、典型应用场景
- 升级验证
-- 升级后立即执行
EXEC DBMS_HCHECK.FULL(container=>'CDB$ROOT');
EXEC DBMS_HCHECK.FULL(container=>'FREEPDB1');
- 空间异常诊断
当出现 ORA-01578 数据块损坏时,通过 CRITICAL 模式快速定位元数据问题。
- 自动化运维
结合调度任务每月执行修复:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04BEGINDBMS_SCHEDULER.CREATE_JOB(job_name => 'HCHECK_REPAIR_JOB',job_type => 'PLSQL_BLOCK',job_action => 'BEGIN SYS.DBMS_DICTIONARY_CHECK.FULL(repair=>TRUE); END;',repeat_interval => 'FREQ=MONTHLY');END;/PL/SQL procedure successfully completed.
- 生产上使用规范
- 修复前必须备份:RMAN> BACKUP CURRENT CONTROLFILE;
- 避免高峰时段执行 FULL 检查