前言:采集程序的本质是“可配置的数据抽取器”
一个成熟的巡检采集程序通常不是“写死一堆 SQL”,而是:
- 有一个启动器负责环境检测与调度
- 有一套配置化采集清单定义:采什么、输出到哪个文件
- 有一个DB/OS 采集引擎负责执行 SQL、读日志、跑命令
- 最终产出一个标准 ZIP 包给后端解析
下面以一个典型 Perl 采集器结构为例讲实现逻辑(不包含敏感信息)。
1. 目录结构与职责划分
常见布局:
runMe.pl:入口启动器(检查环境变量、设置库路径、决定单机/多机模式)conf/BTConfig.pm:核心配置(采集项清单%gResult、全局参数)lib/BTRobot.pl:主采集流程(读取配置 → 连接 DB → 执行采集项)lib/DBTools.pm:数据库访问封装(DBI 连接、执行 SQL、取结果、写文件)data/:结果目录(输出nirvana_*.txt)conf/DBServers.conf:多机批量采集的服务器列表(如需)
2. 启动器 runMe:做环境准备,不做采集
启动器做的事情非常“工程化”:
- 检查
ORACLE_HOME/ORACLE_SID - 设置
PATH/PERL5LIB,确保能用到 Oracle 自带的 Perl/库 - 解析命令行参数(静默模式、多机模式、AWR 时段等)
- 最终
system(perl lib/BTRobot.pl ...)
这种设计的价值是:把“采集逻辑”与“运行环境适配”分离。
3. 配置驱动采集:%gResult 是“采集清单”
核心思想:每个采集项 = 一个输出文件 + 一个数据来源(SQL 或 OS/日志)+ 一组字段定义。
配置示意(概念):
%gResult = (
'RD_DB_INFO' => {
'FILE' => 'nirvana_db_info.txt',
'CLASS' => 'DB',
'SQL' => q{SELECT ... FROM V$DATABASE}
},
'RD_DB_INST' => {
'FILE' => 'nirvana_db_inst.txt',
'CLASS' => 'DB',
'SQL' => q{SELECT ... FROM GV$INSTANCE}
}
);
优势:
- 新增采集项不必大改主流程
- 可按版本区分
SQL_10/SQL_11/SQL_12做兼容 - 输出文件名稳定,后端解析也能稳定匹配
4. DB 采集引擎:连接、执行、写结果
采集引擎一般要解决:
- 连接方式(sysdba / 普通账号 / 服务名)
- 会话 NLS 设置(日期格式、时间戳格式)
- LONG/CLOB 等字段读取长度
- 字符集(UTF8/GBK)适配
- SQL 执行失败重试(可选)
伪代码(概念):
connDB($user, $pwd, $serv);
for each item in %gResult:
if item has SQL:
rows = queryDB(item.SQL)
write_to_file(item.FILE, rows)
else:
collect_from_os_or_log(...)
5. 输出文件为什么叫 nirvana_*.txt?
因为后端解析通常以“稳定文件名”作为契约:
nirvana_md_database.txt:元数据(版本/采集时间/DBID 等)nirvana_db_inst.txt:实例信息nirvana_db_awr_*.txt:AWR 相关nirvana_os_*.txt:操作系统信息
文件名稳定意味着:后端 Loader 可以用配置表驱动解析,而不依赖“遍历 zip 猜文件”。
6. 采集 SQL 都在干什么?(对外解释方法)
对外讲解 SQL,不要陷入逐字段解释,而要按主题:
- 画像类:库/实例/版本/补丁/角色
- 健康类:无效对象、作业、空间、回收站
- 性能类:AWR 快照、系统统计、时间模型、等待事件
- 归档备份类:归档目的地、FRA、日志切换、备份概况(如启用)
这种分组能让读者一眼理解“为什么要采”,而不是被 SQL 吓退。
7. 打包与交付:为什么 ZIP 结构必须标准化
采集端最后一般会:
- 把
data/下的nirvana_*.txt统一编码(建议 UTF-8) - 生成元数据文件
- 以
DBNAME_TIMESTAMP.zip形式打包
只要采集端保证结构稳定,后端就能做到:
- 前置校验(版本/结构)
- 解析容错(按清单加载)
- 报告可复现(同包重跑同结果)
结语
一个“可长期维护”的采集程序,本质是配置驱动 + 引擎稳定 + 输出契约清晰。
当你把“采集包格式”当成 API 来维护,后端解析、分析、展示才能真正形成可进化的系统。