2025-08-28-zabbix5.0创建监控项通过脚本简单实现监控oracle11g的磁盘组和表空间的使用量


title: zabbix5.0创建监控项通过脚本简单实现监控oracle11g的磁盘组和表空间的使用量

authors: Loong

date: 2025-08-28


使用SQLPLUS配合crontab任务

用来执行sql获取信息的脚本

/home/oracle/zabbix_oracle_check.sh

复制代码
#!/bin/bash
#用于zabbix agent被动模式的 非入侵性的检测
#由oracle用户crontab进行巡检 结果存入/tmp下临时文件
#zabbix 脚本去读临时文件
source $HOME/.bash_profile

# 查询语句
#设置sqlplus 
#SET PAGESIZE 9999  设置页大小远大于结果行数(如 9999),这样只输出一次列头和分割线.
#SET FEEDBACK OFF:不显示 6 rows selected. 这类信息。
#SET LINESIZE 9999 设置每行字符数 避免输出中过多的换行
set_sqlplus="
SET PAGESIZE 9999 
SET FEEDBACK OFF
SET LINESIZE 9999
"

DB_STATUS_QUERY="${set_sqlplus}
select instance_name,a.status,b.open_mode,a.inst_id from gv\$instance a,gv\$database b where a.inst_id=b.inst_id;"

TABLESPACE_QUERY="${set_sqlplus}
select * from dba_tablespace_usage_metrics order by used_percent;"

asm_diskgroup_query="${set_sqlplus}
select group_number,name,total_mb,free_mb,((total_mb-free_mb)/total_mb*100) USED_PERCENT from v\$asm_diskgroup;"


# 执行数据库状态检查查询并保存结果到临时文件
DB_STATUS_RESULT_FILE=$(mktemp)
echo "${DB_STATUS_QUERY}" | sqlplus -s / as sysdba > "${DB_STATUS_RESULT_FILE}"
if [ $? -ne 0 ]; then
  echo "数据库状态检查查询失败"
  exit 1
fi

# 执行表空间状态检查查询并保存结果���临时文件
TABLESPACE_RESULT_FILE=$(mktemp)
echo "${TABLESPACE_QUERY}" | sqlplus -s / as sysdba > "${TABLESPACE_RESULT_FILE}"
if [ $? -ne 0 ]; then
  echo "表空间状态检查查询失败"
  exit 1
fi

# 执行asm磁盘组状态检查查询并保存结果到临时文件
asm_diskgroup_RESULT_FILE=$(mktemp)
echo "${asm_diskgroup_query}" | sqlplus -s / as sysdba > "${asm_diskgroup_RESULT_FILE}"
if [ $? -ne 0 ]; then
  echo "asm磁盘组状态检查查询失败"
  exit 1
fi



#处理sed -e '/----/d' -e '/^$/d' -e '/rows selected/d' 删除分割线、空行、影响行数(SET FEEDBACK OFF其实已经具备这个功能了)
sed -i -e '/----/d' -e '/^$/d' -e '/rows selected/d' ${DB_STATUS_RESULT_FILE}
sed -i -e '/----/d' -e '/^$/d' -e '/rows selected/d' ${TABLESPACE_RESULT_FILE}
sed -i -e '/----/d' -e '/^$/d' -e '/rows selected/d' ${asm_diskgroup_RESULT_FILE}

mkdir /tmp/zabbix_oracle_info 2>/dev/null
#处理文本 将多余的空格和制表符替换成一个制表符 
awk '{$1=$1}1' OFS='\t' ${TABLESPACE_RESULT_FILE} > /tmp/zabbix_oracle_info/tablespace_result
awk '{$1=$1}1' OFS='\t' ${asm_diskgroup_RESULT_FILE} > /tmp/zabbix_oracle_info/asm_diskgroup_result
awk '{$1=$1}1' OFS='\t' ${DB_STATUS_RESULT_FILE} > /tmp/zabbix_oracle_info/db_status_result


# 清理临时文件
rm "${DB_STATUS_RESULT_FILE}"
rm "${TABLESPACE_RESULT_FILE}"
rm "${asm_diskgroup_RESULT_FILE}"

脚本权限

复制代码
chown oracle:oinstall /home/oracle/zabbix_oracle_check.sh 
chown +x /home/oracle/zabbix_oracle_check.sh 

定时任务

复制代码
su - oracle
crontab -e
#每1分钟获取一次信息
* * * * * /home/oracle/zabbix_oracle_check.sh

测试结果

复制代码
[oracle@oadb1 ~]$ ls /tmp/zabbix_oracle_info/
asm_diskgroup_result db_status_result      tablespace_result

[oracle@oadb1 ~]$ cat /tmp/zabbix_oracle_info/tablespace_result 
TABLESPACE_NAME                USED_SPACE TABLESPACE_SIZE USED_PERCENT
USERS                                 168         4194302   .004005434
UNDOTBS1                            11728         4194302   .279617443
UNDOTBS2                            11744         4194302   .279998913
TEMP                                18816         4194302   .448608612
ECOLOGY                            563512        20971510   2.68703589
SYSAUX                             304856         4194302    7.2683369
ECOLOGY1                           355184         4194302    8.4682505
SYSTEM                           19499480        20971510   92.9808106

配置zabbix agent用户参数信息获取

测试命令提取

复制代码
[oracle@oadb1 ~]$ cat /tmp/zabbix_oracle_info/tablespace_result | grep -iw system
SYSTEM                           19499480        20971510   92.9808106
[oracle@oadb1 ~]$ cat /tmp/zabbix_oracle_info/tablespace_result | grep -iw system | tail -1 | awk "{print \$NF}"
92.9808106

配置监控项用户参数

复制代码
vim /etc/zabbix/zabbix_agentd.d/oracle.conf
#监控项
UserParameter=oracle.tbs.percent[*], grep -iw "$1" /tmp/zabbix_oracle_info/tablespace_result | tail -1 | awk "{print \$NF}"
UserParameter=oracle.asm.percent[*], grep -iw "$1" /tmp/zabbix_oracle_info/asm_diskgroup_result | tail -1 | awk "{print \$NF}"

需要重启zabbix-agent服务

复制代码
systemctl restart zabbix-agent

在zabbix server上测试

复制代码
#zabbix_get -s 客户端ip -k "oracle.tbs.percent[表空间名]"

[lex@zabbix-server ~]$ zabbix_get -s 10.1.240.21 -k "oracle.tbs.percent[system]"
92.9906144

#zabbix_get -s 客户端ip -k "oracle.asm.percent[磁盘组名]"
zabbix_get -s 10.1.240.21 -k "oracle.asm.percent[arc]"

zabbix web界面配置监控项及触发器

主机-创建监控项

复制代码
名称 Oracle tablespace [system] used in %
键值 oracle.tbs.percent[system]
信息类型 浮点数 
单位 %
更新间隔1分钟

名称 Oracle asm diskgroup [arc] used in %
键值 oracle.asm.percent[arc]
信息类型 浮点数 
单位 %
更新间隔1分钟

添加触发器

复制代码
主机-宏
{$ORACLE.ASM.DISKGROUP.AVERAGE}  80
{$ORACLE.ASM.DISKGROUP.HIGH}  90

{$ORACLE.TBS.AVERAGE} 90
{$ORACLE.TBS.HIGH} 95

创建4个触发器
#表空间system大于一般严重的值80%
名称 Oracle tablespace [system] usage >{$ORACLE.TBS.AVERAGE}%
严重性 一般严重
表达式 {Ecology_DB1:oracle.tbs.percent[system].last()}>{$ORACLE.TBS.AVERAGE}
#表空间system大于严重的值90%
名称 Oracle tablespace [system] usage >{$ORACLE.TBS.HIGH}%
严重性 严重
表达式 {Ecology_DB1:oracle.tbs.percent[system].last()}>{$ORACLE.TBS.HIGH}
#磁盘组arc大于一般严重的值90%
Oracle asm diskgroup [arc] usage >{$ORACLE.ASM.DISKGROUP.AVERAGE}%
一般严重
{Ecology_DB1:oracle.asm.percent[arc].last()}>{$ORACLE.ASM.DISKGROUP.AVERAGE}
#磁盘组arc大于一般严重的值95%
Oracle asm diskgroup [arc] usage >{$ORACLE.ASM.DISKGROUP.HIGH}%
严重
{Ecology_DB1:oracle.asm.percent[arc].last()}>{$ORACLE.ASM.DISKGROUP.HIGH}

进阶:通过自动发现,对多个表空间或磁盘组进行监控

获取信息脚本末尾增加额外的处理脚本

复制代码
#处理文本 将多余的空格和制表符替换成一个制表符 
awk '{$1=$1}1' OFS='\t' tablespace_result > tablespace_result.tsv
awk '{$1=$1}1' OFS='\t' asm_diskgroup_result > asm_diskgroup_result.tsv
awk '{$1=$1}1' OFS='\t' db_status_result > db_status_result.tsv

#生成到同名文件的话
cat tablespace_result | awk  '{$1=$1}1' OFS='\t' > tablespace_result
cat asm_diskgroup_result | awk  '{$1=$1}1' OFS='\t' > asm_diskgroup_result
cat db_status_result | awk  '{$1=$1}1' OFS='\t' > db_status_result

awk 命令来将这些文件中所有连续的空白字符(空格和制表符)分隔的字段,规范化为 单个制表符(Tab)分隔 的标准 TSV 格式。

awk 的默认行为是将连续的空白作为分隔符,并重新以单个空格输出字段。但我们可以通过设置输出字段分隔符 OFS 为制表符 \t,来实现 TSV 格式。

命令解释:

  • {$1=$1}:这是一个技巧,强制 awk 重新构建整行(触发字段重赋值)。
  • 1:是 awk 的"真值",表示对每行执行默认操作(打印)。
  • OFS='\t':设置输出字段分隔符为制表符。

按列名去获取值而不是位置

复制代码
$ sh get_column_value.sh /tmp/zabbix_oracle_info/tablespace_result TABLESPACE_NAME SYSTEM USED_PERCENT
93.1655565

$ cat get_column_value.sh
#!/bin/bash

# 检查参数
if [ $# -ne 4 ]; then
    echo "用法: $0 <文件路径> <列名1> <匹配值> <列名2>"
    echo "例如: $0 /tmp/zabbix_oracle_info/tablespace_result TABLESPACE_NAME SYSTEM USED_PERCENT"
    exit 1
fi

COL1="$2"
VALUE="$3"
COL2="$4"
FILE="$1"

# 检查文件是否存在
if [ ! -f "$FILE" ]; then
    echo "错误: 文件 $FILE 不存在"
    exit 1
fi

# 使用 awk 提取
awk -F'\t' -v c1="$COL1" -v val="$VALUE" -v c2="$COL2" '
BEGIN {
    found = 0
}
NR == 1 {
    # 查找列索引
    for (i = 1; i <= NF; i++) {
        if ($i == c1) idx1 = i
        if ($i == c2) idx2 = i
    }
    if (!idx1) {
        print "错误: 未找到列 \"" c1 "\"" > "/dev/stderr"
        exit 1
    }
    if (!idx2) {
        print "错误: 未找到列 \"" c2 "\"" > "/dev/stderr"
        exit 1
    }
    next
}
{
    if ($idx1 == val) {
        print $idx2
        found = 1
        exit
    }
}
END {
    if (!found && val != "") {
        print ""  # 未找到匹配项,输出空
    }
}
' "$FILE"

按照列名依次获取值生成zabbix自动发现所需的json

复制代码
sh zabbix_oracle_discovery.sh tablespace_result  TABLESPACE_NAME
{
    "data": [
        {"{#TABLESPACE_NAME}": "USERS"},
        {"{#TABLESPACE_NAME}": "TEMP"},
        {"{#TABLESPACE_NAME}": "UNDOTBS2"},
        {"{#TABLESPACE_NAME}": "UNDOTBS1"},
        {"{#TABLESPACE_NAME}": "ECOLOGY"},
        {"{#TABLESPACE_NAME}": "SYSAUX"},
        {"{#TABLESPACE_NAME}": "ECOLOGY1"},
        {"{#TABLESPACE_NAME}": "SYSTEM"}
    ]
}

cat zabbix_oracle_discovery.sh
#!/bin/bash

INPUT_FILE="$1"
COLUMN_NAME="$2"

if [ $# -lt 2 ]; then
    echo "用法: $0 <文件名> <列名>"
    exit 1
fi

if [ ! -f "$INPUT_FILE" ]; then
    echo "错误: 文件 $INPUT_FILE 不存在" >&2
    # 输出合法空 JSON
    echo '{"data": []}'
    exit 1
fi

awk -v col_name="$COLUMN_NAME" '
BEGIN {
    FS = "[ \t]+"
    found_col = 0
    item_count = 0
    print "{"
    print "    \"data\": ["
}
NR == 1 {
    # 查找目标列
    for (i = 1; i <= NF; i++) {
        gsub(/^[ \t]+|[ \t]+$/, "", $i)
        if ($i == col_name) {
            target_col = i
            found_col = 1
        }
    }
    if (!found_col) {
        # 列未找到,输出空数组并结束
        print "    ]"
        print "}"
        exit 0
    }
    next
}
{
    if (!found_col) next
    value = $target_col
    gsub(/^[ \t]+|[ \t]+$/, "", value)
    if (value != "" && value != "N/A" && value != "NULL") {
        if (item_count > 0) {
            printf ",\n"
        }
        printf "        {\"{#%s}\": \"%s\"}", toupper(col_name), value
        item_count++
    }
}
END {
    if (found_col) {
        # 正常结束
        if (item_count == 0) {
            # 没有数据行
            print ""
        }
        print ""
        print "    ]"
        print "}"
    }
    # 如果 !found_col,已在 NR==1 处理
}
' "$INPUT_FILE"

chmod +x /etc/zabbix/zabbix_agentd.d/*.sh

复制代码
[root@localhost zabbix_agentd.d]# cat oracle.conf 
# 自动发现表空间和asm磁盘组
UserParameter=oracle.tbs.discovery,/etc/zabbix/zabbix_agentd.d/zabbix_oracle_discovery.sh /tmp/zabbix_oracle_info/tablespace_result TABLESPACE_NAME
UserParameter=oracle.asm.discovery,/etc/zabbix/zabbix_agentd.d/zabbix_oracle_discovery.sh /tmp/zabbix_oracle_info/asm_diskgroup_result NAME

#UserParameter=oracle.tbs.percent[*], grep -iw "$1" /tmp/zabbix_oracle_info/tablespace_result | tail -1 | awk "{print \$NF}"
#UserParameter=oracle.asm.percent[*], grep -iw "$1" /tmp/zabbix_oracle_info/asm_diskgroup_result | tail -1 | awk "{print \$NF}"
UserParameter=oracle.tbs.percent[*], /etc/zabbix/zabbix_agentd.d/get_column_value.sh /tmp/zabbix_oracle_info/tablespace_result TABLESPACE_NAME "$1" USED_PERCENT
UserParameter=oracle.asm.percent[*], /etc/zabbix/zabbix_agentd.d/get_column_value.sh /tmp/zabbix_oracle_info/asm_diskgroup_result NAME "$1" USED_PERCENT

Zabbix Web 前端配置

新建模板

My Template Oracle asm and tablespace usage

在模板中添加宏

复制代码
{$ORACLE.ASM.DISKGROUP.AVERAGE}  80
{$ORACLE.ASM.DISKGROUP.HIGH}  90
{$ORACLE.TBS.AVERAGE} 90
{$ORACLE.TBS.HIGH} 95

在模板中创建 自动发现规则(Discovery Rule)

  • 进入:配置 → 主机 → 你的 Oracle 主机 → 自动发现
  • 点击 创建发现规则
  • 下面以配置表空间的自动发现规则为例,配置如下:
字段
名称 Oracle Tablespace Discovery
类型 Zabbix agent
键值 oracle.tbs.discovery
更新间隔 1h(或 30m,不需要太频繁)

✅ 保存


创建 发现规则下的监控项原型(Item Prototype)

点击你刚创建的发现规则 → 监控项原型创建监控项原型

字段
名称 Oracle Tablespace {#TABLESPACE_NAME} Used %
类型 Zabbix agent
键值 oracle.tbs.percent[{#TABLESPACE_NAME}]
类型信息 Numeric (float) ✅ 必须是 float
单位 %
更新间隔 1m
应用集 Oracle Tablespace(可创建新应用集)

✅ 保存


(可选)创建 触发器原型(Trigger Prototype)

点击 触发器原型创建触发器原型

字段
名称 Oracle Tablespace {#TABLESPACE} usage > 90%
表达式 {HOSTNAME:oracle.tbs.percent[{#TABLESPACE}].last()} > 90
严重性 High

✅ 保存


附:完整模板

My Template Oracle asm and tablespace usage.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>5.0</version>
    <date>2025-08-29T07:33:05Z</date>
    <groups>
        <group>
            <name>Templates/Databases</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>My Template Oracle asm and tablespace usage</template>
            <name>My Template Oracle asm and tablespace usage</name>
            <description>自定义模板 需要配合agent执行脚本</description>
            <groups>
                <group>
                    <name>Templates/Databases</name>
                </group>
            </groups>
            <discovery_rules>
                <discovery_rule>
                    <name>auto-discovery asm-diskgroup</name>
                    <key>oracle.asm.discovery</key>
                    <delay>30m</delay>
                    <item_prototypes>
                        <item_prototype>
                            <name>Oracle ASM diskgroup {#NAME} Used %</name>
                            <key>oracle.asm.percent[{#NAME}]</key>
                            <value_type>FLOAT</value_type>
                            <trigger_prototypes>
                                <trigger_prototype>
                                    <expression>{last()}&gt;{$ORACLE.ASM.DISKGROUP.AVERAGE}</expression>
                                    <name>Oracle asm diskgroup [{#NAME}] usage &gt;{$ORACLE.ASM.DISKGROUP.AVERAGE}%</name>
                                    <priority>AVERAGE</priority>
                                </trigger_prototype>
                                <trigger_prototype>
                                    <expression>{last()}&gt;{$ORACLE.ASM.DISKGROUP.HIGH}</expression>
                                    <name>Oracle asm diskgroup [{#NAME}] usage &gt;{$ORACLE.ASM.DISKGROUP.HIGH}%</name>
                                    <priority>HIGH</priority>
                                </trigger_prototype>
                            </trigger_prototypes>
                        </item_prototype>
                    </item_prototypes>
                </discovery_rule>
                <discovery_rule>
                    <name>auto-discovery tablespace</name>
                    <key>oracle.tbs.discovery</key>
                    <delay>30m</delay>
                    <item_prototypes>
                        <item_prototype>
                            <name>Oracle Tablespace {#TABLESPACE_NAME} Used %</name>
                            <key>oracle.tbs.percent[{#TABLESPACE_NAME}]</key>
                            <value_type>FLOAT</value_type>
                            <trigger_prototypes>
                                <trigger_prototype>
                                    <expression>{last()}&gt;{$ORACLE.TBS.AVERAGE}</expression>
                                    <name>Oracle tablespace [{#TABLESPACE_NAME}] usage &gt;{$ORACLE.TBS.AVERAGE}%</name>
                                    <priority>AVERAGE</priority>
                                </trigger_prototype>
                                <trigger_prototype>
                                    <expression>{last()}&gt;{$ORACLE.TBS.HIGH}</expression>
                                    <name>Oracle tablespace [{#TABLESPACE_NAME}] usage &gt;{$ORACLE.TBS.HIGH}%</name>
                                    <priority>HIGH</priority>
                                </trigger_prototype>
                            </trigger_prototypes>
                        </item_prototype>
                    </item_prototypes>
                </discovery_rule>
            </discovery_rules>
            <macros>
                <macro>
                    <macro>{$ORACLE.ASM.DISKGROUP.AVERAGE}</macro>
                    <value>80</value>
                </macro>
                <macro>
                    <macro>{$ORACLE.ASM.DISKGROUP.HIGH}</macro>
                    <value>90</value>
                </macro>
                <macro>
                    <macro>{$ORACLE.TBS.AVERAGE}</macro>
                    <value>90</value>
                </macro>
                <macro>
                    <macro>{$ORACLE.TBS.HIGH}</macro>
                    <value>95</value>
                </macro>
            </macros>
        </template>
    </templates>
</zabbix_export>