# 表空间、服务器体检与 Oracle 运维监控 > 本文件由 SKILL.md 整理拆分而来,保留原说明内容。 ## 表空间查询 查询 Oracle 表空间使用情况。 ### 自动降级策略 脚本按优先级尝试**5 种方式**,无需人工切换: | 优先级 | 方式 | 数据来源 | 条件 | 输出字段 | |:---:|------|----------|------|----------| | 1️⃣ | 直接 DBA 查询 | `DBA_DATA_FILES` + `DBA_FREE_SPACE` | 用户有 `SELECT_CATALOG_ROLE` | 全部 8 个字段 | | 2️⃣ | DBA 专用函数 | `sys.get_tablespace_usage()`(返回 SYS_REFCURSOR) | DBA 已执行 CREATE FUNCTION + GRANT | 全部 5 个字段(自动解析) | | 3️⃣ | DBA 授权 VIEW(无前缀) | `HENLO_TS_USAGE` 视图 | DBA 已执行授权 SQL | 全部 8 个字段 | | 4️⃣ | DBA 授权 VIEW(sys.前缀) | `SYS.HENLO_TS_USAGE` 视图 | DBA 以 SYS 身份创建时自动处理 | 全部 8 个字段 | | 5️⃣ | 用户视图 | `USER_FREE_SPACE` | 始终可用 | 仅表空间名称 + 剩余MB | > **经验**:DBA 以 SYS 身份登录创建的 VIEW 会归属到 `SYS` schema,需用 `sys.HENLO_TS_USAGE` 查询。脚本会自动先试无前缀、再试 `sys.` 前缀。 ### 给 DBA 的授权 SQL 如果当前用户缺少系统视图权限,脚本会**自动输出**以下 SQL。将其交给 DBA 在 Oracle 中执行一次: ```sql CREATE OR REPLACE VIEW SYS.HENLO_TS_USAGE AS SELECT df.tablespace_name AS "表空间名称", ROUND(df.total_bytes / 1048576, 1) AS "总大小MB", ROUND((df.total_bytes - NVL(fs.free_bytes, 0)) / 1048576, 1) AS "已用MB", ROUND(NVL(fs.free_bytes, 0) / 1048576, 1) AS "剩余MB", ROUND((df.total_bytes - NVL(fs.free_bytes, 0)) / df.total_bytes * 100, 1) AS "使用率%", df.autoextensible AS "自动拓展", ROUND(df.max_bytes / 1048576, 1) AS "最大可拓展MB", ROUND((df.total_bytes - NVL(fs.free_bytes, 0)) / NULLIF(df.max_bytes, 0) * 100, 1) AS "最大使用率%" FROM ( SELECT tablespace_name, SUM(bytes) AS total_bytes, SUM(CASE WHEN autoextensible = 'YES' THEN maxbytes ELSE bytes END) AS max_bytes, MAX(CASE WHEN autoextensible = 'YES' THEN 'YES' ELSE 'NO' END) AS autoextensible FROM dba_data_files GROUP BY tablespace_name ) df LEFT JOIN ( SELECT tablespace_name, SUM(bytes) AS free_bytes FROM dba_free_space GROUP BY tablespace_name ) fs ON df.tablespace_name = fs.tablespace_name ORDER BY 6 DESC; GRANT SELECT ON SYS.HENLO_TS_USAGE TO bosnds3; ``` > **原理**:Oracle 视图默认使用**定义者权限**(`DEFINER`),以视图创建者的 DBA 身份执行,普通用户仅需视图的 `SELECT` 权限。这比授予 `SELECT_CATALOG_ROLE` 更安全——只暴露这一个视图的数据。 DBA 执行授权后,再次运行 `tablespace` 命令即可自动使用完整查询。 ### 输出字段 | 字段 | 说明 | |------|------| | 表空间名称 | 表空间名称 | | 总大小MB | 当前所有数据文件总大小 | | 已用MB | 已使用的空间 | | 剩余MB | 剩余可用空间 | | 使用率% | 已用 / 总大小 × 100% | | 自动拓展 | YES=自动扩展,NO=不自动扩展 | | 最大可拓展MB | 开启自动扩展后的最大可达大小 | | 最大使用率% | 已用 / 最大可拓展 × 100%(参考阈值 5%) | ### 触发语法 用户可以说: - 「帮我查询下表空间」 - 「查看表空间使用情况」 - 「表空间是否够用」 ```bash python oracle_skill.py tablespace # 或 python oracle_skill.py tablespaces ``` ### 阈值规则 | 使用率 | 状态 | 建议 | |--------|------|------| | < 80% | ✅ 正常 | 无需处理 | | 80~95% | 🔶 关注 | 评估未来增长,制定扩容计划 | | ≥ 95% | ⚠️ 紧急 | 尽快扩容或清理空间! | > **智能告警规则**:脚本逐行解析表空间数据,自动判断衡量指标。 > 若表空间**已开启自动扩展**(`自动拓展=YES`),按 **最大使用率%** 判断(已用/最大可拓展); > 若**未开启**(`NO`),按当前 **使用率%** 判断(已用/当前总大小)。 > > 这让告警更准确。例如:SYSTEM 使用率 99.4% 但最大使用率仅 3.7%,说明只是当前数据文件写满了,自动扩展后即释放空间,并非真正的存储瓶颈。 ### 使用场景 1. **查主表的明细表**:通过 AD_REFBYTABLE 找到主表关联的所有明细表及外键列 2. **查字段含义**:通过 AD_COLUMN 的 DESCRIPTION 字段了解业务含义 3. **构建 JOIN 查询**:根据外键列名自动拼接主表→明细表的 JOIN 条件 4. **理解业务模型**:通过表间关系理解业务单据结构(如零售单→零售明细→支付明细) ### 4. 统计数据场景的过滤条件 在 BOS 系统中,进行统计数据查询时,必须遵循以下业务规则: **业务单据通用过滤条件**: - `ISACTIVE = 'Y'`:单据有效(Y=可用,N=已删除/作废) - `STATUS = '2'`:单据已提交(1=未提交,2=已提交,3=审批中) **查询模板**: ```sql -- 查询有效且已提交的业务单据 SELECT * FROM <业务表名> WHERE ISACTIVE = 'Y' AND STATUS = '2' -- 其他业务条件... ``` **字段含义**: | 字段 | 值 | 业务含义 | |------|-----|----------| | `ISACTIVE` | 'Y' | 单据有效,可参与统计 | | `ISACTIVE` | 'N' | 单据已删除/作废,应排除 | | `STATUS` | '1' | 草稿/未提交,应排除 | | `STATUS` | '2' | **已提交**,可参与统计 | | `STATUS` | '3' | 审批中,通常排除(除非统计审批流程) | **应用场景**: - 统计销售额、销售量 → 必须用 `ISACTIVE='Y' AND STATUS='2'` - 查询历史订单 → 必须用 `ISACTIVE='Y' AND STATUS='2'` - 分析业务趋势 → 必须用 `ISACTIVE='Y' AND STATUS='2'` **注意事项**: 1. 明细表(如 M_RETAILITEM)通常继承主表状态,但有时也有自己的状态字段 2. 部分表可能使用 `ISSTOP` 代替 `ISACTIVE`,逻辑相反('Y'=停用) 3. 查询前应先通过 AD_COLUMN 确认字段名和值域 ## Oracle 日常运维监控触发 当用户说“给我 HENLO 的 Oracle 运维报告”、“生成 HENLO 数据库日报”、“做一次 HENLO Oracle 巡检”这类请求时,调用: ```bash python scripts/oracle_skill.py ops_report HENLO ``` 当用户询问单项运维状态时,调用 `ops [clientCode]`: ```bash python scripts/oracle_skill.py ops blocking_locks HENLO python scripts/oracle_skill.py ops active_slow_sql HENLO python scripts/oracle_skill.py ops ora_errors HENLO ``` 常用自然语言映射: | 用户意图 | 命令 | |---|---| | 有没有锁阻塞 | `ops blocking_locks ` | | 当前有没有慢 SQL | `ops active_slow_sql ` | | 最近 ORA 错误 | `ops ora_errors ` | | UNDO 风险 | `ops undo ` | | IO 等待 | `ops io_waits ` | | 内存使用 | `ops memory ` | | 失效对象 | `ops invalid_objects ` | 涉及 SYS/DBA 权限视图时,Agent 会优先调用 `SYS.HENLO_ORA_MONITOR`;如果不可用,再尝试当前登录账号下的 `HENLO_ORA_MONITOR`。如果两个函数都不存在或未授权,输出两种安装方案:有 SYS 账号时安装到 SYS 并授权;没有 SYS 账号但当前登录账号已有系统视图查询权限时,安装到当前账号后重试。 ## 服务器巡检报告触发 当用户说“给我 HENLO 的服务器体检报告”、“查询 HENLO 的服务器状态”、“看看 HENLO 的备份情况”、“生成巡检 HTML”这类请求时,统一使用归档巡检入口: ```bash python scripts/oracle_skill.py inspection_report HENLO python scripts/oracle_skill.py inspection_latest HENLO python scripts/oracle_skill.py inspection_latest HENLO --refresh python scripts/oracle_skill.py inspection_report HENLO --markdown ``` `inspection_report` 会实时请求 Agent 的 `inspection_report_data` 并归档到 `TS_INSPECTION_REPORT`;`inspection_latest` 默认读取最近一次历史快照,加 `--refresh` 时重新采集并返回。三个巡检命令成功后均默认使用固定格式模板导出 HTML,保证每次结构一致,只替换数据内容;增加 `--markdown`(或 `--md`)可同时导出固定格式 Markdown。 当前巡检数据包括服务器 IP、操作系统版本、启动时间、运行时长、关键进程、TCP 连接状态、Oracle ACTIVE/总会话数,以及 Buffer Cache、Library Cache 命中率。TCP 连接统计与 Oracle 会话数是两个独立指标,不混合计算。 ## AWR 报告 AWR 仅在客户 DBA 明确确认 Diagnostics Pack 授权,且 Agent 同时配置 `awr.enabled=true`、`awr.license_confirmed=true` 后启用。Skill 不执行授权 SQL,不随日常巡检隐式生成 AWR,也不在本地重新渲染 HTML。 当 `awr_status` 返回 `permission_required` 时,Skill 会从目标 Agent 的 `version` action 解析实际 Oracle schema,并返回已替换账号的 `HENLO_AWR_EXPORT` 创建/授权 SQL,供 DBA 在确认 Diagnostics Pack 授权后手工执行。无法解析有效 schema 时停止输出 SQL,不保留 `` 占位符。 `HENLO_AWR_EXPORT` v1.1 对 Oracle AWR 报告流中的空输出行进行保护,避免把 `LENGTH(NULL)` 传给 `DBMS_LOB.WRITEAPPEND` 触发 `ORA-06502`;每个输出行后追加换行,保持 HTML 原始行边界。若旧版函数已生成 `skipped` 元数据,先由 DBA 手工升级函数,再升级并重启 Agent `1.8.12+` 触发一次恢复重试。 ```powershell python scripts/oracle_skill.py awr_status WEIRUI python scripts/oracle_skill.py awr_list WEIRUI python scripts/oracle_skill.py awr_download WEIRUI 20260720 ``` Agent 默认在东八区每日 01:00 尝试生成前一日 AWR,并按配置保留本地文件。`awr_download` 经 transit-server 权限校验后原样下载 Agent 文件,默认保存到 `outputs/AWR--.html`,最大 50 MB。AWR 失败不影响服务器基础巡检、Oracle 会话和缓存命中率等常规项目。