☰
Zabbix+orabbix 1.2.3监控Oracle数据库:从部署到实战排查全记录
2026/10/20 17:36:37 网站建设 项目流程

监控Oracle数据库这件事,我踩过不少坑,也试过不少方案。从最早期的纯shell脚本定时采集,到后来自己折腾Perl脚本往Zabbix里灌数据,再到最终选定orabbix 1.2.3作为生产环境的监控方案,整个过程说实话挺折腾的。这篇博文就把我基于Zabbix + orabbix 1.2.3监控Oracle数据库的完整经验梳理一遍,从选型逻辑、部署细节、Zabbix端配置到排查实录,尽量把能想到的都写清楚,给正在走这条路的朋友一个参考。

1. 为什么选orabbix:监控Oracle的几种主流路径对比

1.1 直接写脚本采集的痛点

我最初给Oracle做监控的时候,用的是最原始的方式:写Shell脚本,通过sqlplus连上数据库执行一堆SQL,把结果解析成Zabbix能识别的格式,然后用zabbix_sender推送到服务端。这种方案看起来简单直接,但实际上维护成本非常高。原因在于Oracle的监控指标太多了,会话数、活跃会话、表空间使用率、SGA命中率、PGA使用情况、等待事件、归档日志频率、锁等待……每个指标都要单独写SQL、单独做解析,脚本数量一多,管理起来就是一团乱麻。

而且脚本方案还有一个很麻烦的问题:Oracle的v$视图在不同版本下字段有差异,比如v$session在Oracle 11g和19c里某些字段的语义就不完全一样。今天这个脚本在11g上跑得好好的,明天换到19c上就可能报错或者返回空值。每次数据库升级,脚本就要跟着调一轮,属实折磨。

1.2 Zabbix原生ODBC监控的局限

后来Zabbix推出了ODBC监控方式,理论上可以直接通过ODBC连接Oracle执行SQL采集数据。我在测试环境实际试了一把,发现了几个实际别扭的地方:

  • 配置麻烦。Zabbix Server端要装ODBC驱动,还要在odbc.ini里维护DSN,一套下来涉及系统库、驱动版本、字符集等多层配置,任何一个不对都连接不上。
  • 性能开销不可控。Zabbix Server在每次轮询时直接连数据库执行SQL,如果监控项多、轮询间隔短,对数据库本身会产生额外的连接和查询压力。生产库上我不敢这么干。
  • 大多数现成模板不适用。官方自带的Oracle模板监控项其实挺有限的,更多时候还是要自己写SQL、自己创建监控项,工作量并没有比脚本方案省多少,反而把Zabbix Server和Oracle数据库耦合得更紧密了。

1.3 orabbix的设计思路和适用场景

orabbix是一个基于Java的独立守护进程,专门做Oracle监控数据采集转发。它的工作方式有点像外贸公司里面的报关行:你不直接去对接海关,而是把需要申报的资料交给报关行,由他们统一处理、统一递交。

具体到orabbix,它做的事情是:

  • 通过JDBC连接你的Oracle数据库,周期性执行预先定义好的SQL查询;
  • 把查询结果按照Zabbix trapper协议的格式打包成JSON;
  • 通过Zabbix Sender协议推送到Zabbix Server的10051端口。

这套设计的好处在于:orabbix在数据库和Zabbix Server之间做了一层隔离,Zabbix Server永远不需要直连数据库,全部数据都走orabbix这个中转。同时,orabbix是一个常驻进程,连接池复用机制比脚本临时起sqlplus要稳健得多,采集频率也可以控制得更细。

orabbix 1.2.3虽然不是什么新版本了,但它在生产环境中的稳定性经过了大量验证,社区积累的问题排查资料也比较丰富。如果你的Zabbix版本在4.x到6.x之间,搭配orabbix 1.2.3完全够用。如果目标仅仅是常规的健康检查、性能趋势分析、告警阈值控制,orabbix是一个性价比很高的选择。

2. 部署前的准备:架构规划、环境依赖和数据库账号

2.1 部署架构与端口依赖

我建议把orabbix部署在一台独立的监控采集服务器上,而不是直接塞进Zabbix Server所在机器。虽然orabbix本身比较轻量,但独立部署的好处是:采集任务的资源消耗(CPU、内存、网络)不会和Zabbix Server本身产生资源竞争,排查问题的时候边界也清晰得多。

orabbix需要访问两类端口:

通信方向目标端口用途
orabbix → Zabbix Server10051推送监控数据(trapper协议)
orabbix → Oracle数据库1521JDBC连接数据库执行查询

如果你在orabbix采集机上有防火墙,一定要提前把这些端口的出口规则放行。我见过不少初次部署的朋友,Zabbix Server端配置全做对了,orabbix也启动成功了,但最新数据就是迟迟不出现,查到最后发现是采集机到Zabbix Server的10051端口被防火墙拦了。

2.2 环境依赖:JDK版本和目录规划

orabbix是Java写的,所以Java运行环境是前提。但我建议不要在太老的JDK版本上运行,实测JDK 1.8是最稳的,JDK 11也遇到过能跑的情况但个别JDBC驱动类加载行为有差异,不如1.8省心。如果你服务器上还没有JDK,装一个OpenJDK 8就行:

yum install -y java-1.8.0-openjdk java -version

orabbix的安装其实是个绿色解压的过程,不需要什么复杂的安装器。我习惯把它的部署目录固定在/opt/orabbix,方便脚本和服务文件引用。解压后的核心结构大概是这样:

/opt/orabbix ├── conf/ │ ├── config.props │ └── query.props ├── lib/ │ ├── orabbix-1.2.3.jar │ ├── ojdbc6.jar │ └── ... ├── log/ │ └── orabbix.log ├── orabbix └── run.sh

从官网或社区下载到的压缩包一般是不带ojdbc驱动jar包的,需要你自己去找对应Oracle版本的JDBC驱动。Oracle 11g用ojdbc6.jar,Oracle 12c/19c建议用ojdbc8.jar。这个细节特别容易被忽略,我最初用ojdbc6去连Oracle 19c,启动时直接报不支持的驱动版本异常。

2.3 创建Oracle专用监控账号

这一步非常关键,也是很多新手掉坑的地方。千万不要用sys或system这种高权限账号去跑监控,安全性不说,一旦监控SQL写得不严谨出现了资源消耗较大的查询,可能拖累生产库。正确的做法是创建一个专用账号,只授予它读取监控所需视图的权限。

下面是我常用的创建脚本:

CREATE USER ZABBIX IDENTIFIED BY "Your_Strong_Password"; GRANT CONNECT TO ZABBIX; GRANT SELECT ON V_$SESSION TO ZABBIX; GRANT SELECT ON V_$SYSTEM_EVENT TO ZABBIX; GRANT SELECT ON V_$SYSSTAT TO ZABBIX; GRANT SELECT ON V_$PARAMETER TO ZABBIX; GRANT SELECT ON V_$TABLESPACE TO ZABBIX; GRANT SELECT ON V_$DATAFILE TO ZABBIX; GRANT SELECT ON V_$SGA TO ZABBIX; GRANT SELECT ON V_$PGASTAT TO ZABBIX; GRANT SELECT ON V_$PROCESS TO ZABBIX; GRANT SELECT ON V_$LOCK TO ZABBIX; GRANT SELECT ON V_$LATCH TO ZABBIX; GRANT SELECT ON V_$LIBRARYCACHE TO ZABBIX; GRANT SELECT ON DBA_DATA_FILES TO ZABBIX; GRANT SELECT ON DBA_FREE_SPACE TO ZABBIX; GRANT SELECT ON DBA_TABLESPACES TO ZABBIX;

如果你图省事,直接GRANT SELECT_CATALOG_ROLE TO ZABBIX;也行,这个角色包含了绝大多数v$视图的查询权限。但我在生产环境还是倾向于最小化授权,一则安全,二则出问题的时候排查思路更清晰:监控查不到数据,先怀疑权限,再怀疑网络和配置。

特别提醒:如果数据库是RAC集群,最好在每个实例上都执行一遍授权,避免某个节点上出现权限缺失的偶发问题。

3. 部署全流程实录:从解压到开机自启

3.1 安装包准备和解压

先去社区把orabbix 1.2.3的压缩包下下来。然后把包放到规划好的目录里解压:

mkdir -p /opt/orabbix tar -zxvf orabbix-1.2.3.tar.gz -C /opt/orabbix

解压完之后,记得把JDBC驱动jar包放入/opt/orabbix/lib/目录。这个步骤不要省,orabbix启动时要通过类加载器加载驱动类,如果lib下找不到ojdbc开头的jar包,直接抛ClassNotFoundException。

3.2 config.props核心配置逐项拆解

orabbix的主配置文件在/opt/orabbix/conf/config.props。这是我踩过最多坑的地方,每一项都得仔细看。

下面是一个实际可用的配置片段:

# Zabbix Server列表,多个用逗号分隔 ZabbixServerList=10.10.10.20:10051 # orabbix自身作为采集端标识 OrabbixDaemon.PidFile=./orabbix.pid OrabbixDaemon.Name=OrabbixDaemon # 数据库连接池配置 DatabaseList=ORCL_PROD,ORCL_TEST # 每个数据库的连接URL、账号、密码 ORCL_PROD.Url=jdbc:oracle:thin:@10.10.10.30:1521/orcl ORCL_PROD.User=zabbix ORCL_PROD.Password=Your_Strong_Password ORCL_PROD.MaxActive=10 ORCL_PROD.MaxWait=1000 ORCL_TEST.Url=jdbc:oracle:thin:@10.10.10.31:1521/orcl ORCL_TEST.User=zabbix ORCL_TEST.Password=Your_Strong_Password ORCL_TEST.MaxActive=5 ORCL_TEST.MaxWait=1000 # 查询文件定义文件 QueryFile.Load=query.props # 采集线程池大小,建议和数据库数量保持一定比例 ThreadPoolSize=10

其中几个关键参数我再展开说下:

  • ZabbixServerList:这里填的是Zabbix Server的IP和10051端口。注意如果Zabbix Server有多个节点(HA或集群),可以用逗号分隔多个地址,orabbix会尝试轮流推送。
  • DatabaseList:这个列表名要和后面每个数据库的URL前缀保持完全一致。比如你定义了DatabaseList=ORCL_PROD,ORCL_TEST,那么每个库的URL配置就分别对应ORCL_PROD.Url和ORCL_TEST.Url。前缀不一致的话,orabbix启动时读取配置就会漏掉库。
  • MaxWait:单位是毫秒,指的是连接池获取连接的最大等待时间。如果数据库繁忙导致连接获取超时,orabbix会记录异常并跳过本次采集。这个建议不要设太短,否则高峰期容易产生大量采集失败告警。

3.3 query.props查询文件的定制思路

query.props是orabbix的监控查询定义文件。每一行定义一个查询项,格式为:

<监控项名称> = <SQL查询语句>

orabbix内置了很多常用查询,比如活动会话数、逻辑读、物理读、表空间使用率等等。但我建议你在实际使用前,先通读一遍内置的查询,确认哪些是符合你需求的,哪些查询在你的Oracle版本上有兼容性问题,然后根据实际情况做增删。

举个例子,默认查询文件里可能有一项:

active.session.count = SELECT COUNT(*) AS value FROM V$SESSION WHERE STATUS='ACTIVE'

这个查询返回单个数值,orabbix会把值作为orabbix.<数据库名>.active.session.count这个key推送到Zabbix。数据库名就是你在config.props里定义的前缀,比如上文配置里的ORCL_PROD,最终完整key就是orabbix.ORCL_PROD.active.session.count。

如果想自定义一个监控项,比如查看当前数据库的等待事件数量,可以新增一行:

wait.class.count = SELECT COUNT(*) AS value FROM V$SESSION_WAIT WHERE WAIT_TIME=0

同理,如果你想监控某些自定义的表数据,也完全可以在这个文件里追加SQL。这里有个原则:只要能返回单行单列数值的SQL,orabbix都能采集。但需要注意查询性能,监控SQL本身必须控制在毫秒级,否则可能拖累数据库性能。

3.4 启动orabbix和systemd开机自启

orabbix解压目录下有一个run.sh脚本,可以直接启动服务。但我强烈建议配置成systemd服务,这样开机自启、崩溃自动拉起、日志管理都更方便。

在/etc/systemd/system/orabbix.service写入以下配置:

[Unit] Description=Orabbix Daemon After=network.target [Service] Type=simple WorkingDirectory=/opt/orabbix ExecStart=/usr/bin/java -jar /opt/orabbix/lib/orabbix-1.2.3.jar -c /opt/orabbix/conf/config.props Restart=always RestartSec=10 User=orabbix Group=orabbix [Install] WantedBy=multi-user.target

这里我特意建了一个独立的系统用户orabbix来跑服务,没有直接用root。好处是:即使orabbix因某些未知漏洞被攻破,攻击者拿到的也只是一个低权限账号,影响面可控。运维的很多安全感就是从这些细节里累积出来的。

写完之后执行:

systemctl daemon-reload systemctl start orabbix systemctl enable orabbix systemctl status orabbix

启动后立刻看一下日志文件/opt/orabbix/log/orabbix.log,确认有没有报错。正常启动时,日志里会逐行打印已加载的数据库连接配置和查询文件,最后大概会出现一句Orabbix Daemon started之类的字样。

4. Zabbix端配置:模板、主机和验证数据链路

4.1 导入官方模板

orabbix安装包自带一个模板文件,文件名一般是orabbix_template.xml之类。在Zabbix前端界面里,通过“配置 → 模板 → 导入”把这个文件导入即可。

模板导入后,你会看到里面定义了一组监控项,大部分类型都是“Zabbix捕获器”(也就是trapper),也就是Zabbix Server不会主动去采集数据,而是被动接收orabbix推过来的数据。理解这个逻辑很重要:如果你给某个告警配置了触发器,但orabbix没有采集到对应的key数据,触发器状态就会变成“不支持”,而不是“正常”。

4.2 主机关联模板和宏替换

把需要监控的Oracle主机(实际上对应的是orabbix里定义的数据库标识)和模板关联起来。在主机配置页面里,添加模板,然后检查一下模板里的宏定义。

orabbix模板里通常会用到一些宏,例如:

宏含义我的配置建议
{$ORABBIX_DB_NAME}数据库标识(对应config.props中的DatabaseList前缀)填ORCL_PROD

这个宏决定了最终匹配的key里的数据库名部分,必须和config.props里定义的前缀完全一致,否则orabbix推送的数据到了Zabbix里会被丢弃,因为Zabbix只接收和监控项key精确匹配的数据。

4.3 验证采集数据是否正常

配置完成后,别急着画图。先确认数据链路通了:

第一步,在Zabbix前端进入“监测 → 最新数据”,筛选刚才关联的主机,看看有没有数据出现。正常情况下,配置正确的话,一两分钟内就能看到orabbix推送过来的数据。

如果看不到数据,可以用zabbix_get从Zabbix Server上主动测试一下:

zabbix_get -s 127.0.0.1 -k "orabbix.ORCL_PROD.active.session.count"

不过这里有个坑:zabbix_get走的是被动模式(10050端口),而orabbix推数据走的是主动模式(10051端口),两者不能完全互相替代。更好的验证手段还是看Zabbix Server的日志,以及orabbix自身的日志。

我一般直接在orabbix服务器上看最新的日志,确认是否有成功push的痕迹:

tail -f /opt/orabbix/log/orabbix.log

还有一个小技巧:在Zabbix Server上用tcpdump抓10051端口的包,看看有没有来自orabbix服务器IP的数据包:

tcpdump -i eth0 port 10051 -nn

这么做能快速确认网络层面是否通,把问题缩小到orabbix进程或Zabbix Server配置这两个环节。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

先整理一个速查表,都是我在部署orabbix 1.2.3过程中真实遇到过的,以及身边同行踩过的坑:

问题症状可能原因排查与解决办法
orabbix启动后日志报ClassNotFoundException: oracle.jdbc.driver.OracleDriverlib目录下缺少ojdbc驱动jar包下载对应Oracle版本的ojdbc驱动放入lib目录
Zabbix最新数据为空Zabbix Server 10051端口不通检查防火墙,用telnet 目标IP 10051验证
部分监控项有数据,部分是nullOracle账号权限不足检查是否授予了对应v$视图的查询权限
所有监控项都有但数值为0SQL查询返回异常或数据库确实空闲先手工执行对应查询确认返回值
日志提示连接池获取连接超时数据库连接数满或JDBC URL写错检查Oracle的连接数,确认SERVICE_NAME是否正确
key变成“不支持”状态宏配置与config.props前缀不一致核对数据库标识,修改宏为准
推送到Zabbix Server的数据含乱码字符集不匹配在config.props里设置合适的NLS参数

5.2 印象最深的三个坑

第一个坑是JDBC驱动版本不兼容。我最初用ojdbc6连接Oracle 19c,orabbix虽然启动正常,但一旦执行稍微复杂点的SQL就报错,日志里能看到一堆奇怪的SQLException。后来换成了ojdbc8之后,这个世界马上清净了。所以,数据库版本和驱动版本的匹配关系,一定要在部署前就查清楚,不要等出问题了再去折腾。

第二个坑是Oracle账号权限。有一个测试库,orabbix部署好之后,大约有一半的监控项查不到数据,当时我以为是网络或者配置问题,排查了好久。后来手工用zabbix账号去执行那些SQL,才发现直接报insufficient privileges。原因是某些v$视图(尤其是v$sysstat、v$latch这类)需要额外的授权。补齐授权之后,所有监控项立即恢复数据。这个经验给我的教训是:首次部署时,不要只给账号授几个视图的权限就完事,先统一授SELECT_CATALOG_ROLE,验证所有监控项都有数据了,再根据实际需要逐步收权。

第三个坑是表空间使用率监控项的算法口径问题。orabbix内置的表空间使用率查询在不同Oracle版本上,dba_free_space和dba_data_files的关联逻辑有差异。如果数据库有OMF特性或者使用了ASM,默认查询的结果会和你在Enterprise Manager里看到的数值对不上。遇到这类问题,别迷信内置查询,直接用你熟悉的表空间计算SQL替换掉query.props里的对应项即可。监控是为了反映真实情况,而不是为了凑齐所有监控项。

5.3 日志级别调优的补充建议

orabbix默认日志级别比较粗放,排查问题的时候可以通过config.props里的日志配置来打开更详细的输出,定位是连接失败还是查询失败还是推送失败。生产环境上我一般会把日志调整到INFO级别,确认稳定运行后再调回来。日志文件记得配一下logrotate,不然时间长了log文件会把磁盘撑爆。这不是危言耸听,orabbix日志在DEBUG级别下一天能写几个GB。

6. 生产环境运行的心得与后续扩展

orabbix 1.2.3这个方案在生产环境跑了两年多,整体稳定性我还是满意的。但我有一点体会特别深:监控工具的部署只是开始,监控项的维护才是长期工作。比如Oracle版本升级、新增表空间、应用高峰期出现新的等待事件,都需要你持续回访和调整orabbix的查询配置,而不是部署完就抛之脑后。

另外,orabbix的告警阈值不要拍脑袋定。以表空间使用率为例,如果你的数据文件是自动扩展的,那么75%可能并不紧急;但如果数据文件是固定大小的,75%可能已经需要告警了。所以阈值的设置一定要结合业务特征和数据库架构特性来定,而且要在真实故障场景中反复校准。

还有一个小技巧分享:如果你需要快速验证某个新增的监控SQL是否有效,不用重启orabbix,直接在Oracle客户端手工执行一遍,确认返回值和格式,再决定要不要加进query.props。毕竟每次修改orabbix配置并重启服务,都会造成一小段时间的数据采集空窗,生产环境上这种空窗能避免就尽量避免。

最后说说后续扩展。orabbix 1.2.3本身的功能边界很清楚,它适合做常规的Oracle性能与容量监控。如果你有更高的需求,比如监控执行计划变化、AWR报告自动分析,那可能需要引入其他工具搭配使用。但作为Zabbix生态下Oracle监控的入口方案,orabbix的实践价值和稳定性是经过验证的,值得你认真把玩一遍。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询