生产环境推荐使用V$TABLESPACE_USAGE_METRICS查ASSM表空间使用率,因其实时反映段级使用且避免延迟块清除误判;临时表空间需用V$TEMP_SPACE_HEADER。
查表空间使用率超过阈值的SQL怎么写
直接用 dba_tablespaces 和 dba_data_files 关联查已用空间,但更准的是基于 dba_segments 或 v$tablespace_usage_metrics(11gr2+)。生产环境推荐后者,它实时反映 assm 表空间的段级使用,避免因延迟块清除导致的误判。
关键点:别只看 bytes / maxbytes,要算「已分配未使用」空间——V$TABLESPACE_USAGE_METRICS.USED_SPACE 是真实已用块数,乘以 block_size 才是准确字节数。
- 示例阈值告警SQL(90%):
SELECT tablespace_name, ROUND(used_space * 8192 / 1024/1024/1024, 2) used_gb, ROUND(tablespace_size * 8192 / 1024/1024/1024, 2) total_gb, ROUND(used_space / tablespace_size * 100, 2) pct_used FROM V$TABLESPACE_USAGE_METRICS WHERE used_space / tablespace_size > 0.9; -
V$TABLESPACE_USAGE_METRICS不包含临时表空间,查临时表空间得用V$TEMP_SPACE_HEADER - 如果数据库版本 DBA_DATA_FILES +
DBA_FREE_SPACE计算,注意autoextensible = 'YES'的文件要按maxbytes算上限,否则会低估容量
如何用shell脚本定时执行并触发邮件告警
Oracle 自带 sqlplus 就够用,不依赖额外工具。重点不是“怎么发邮件”,而是“怎么让 Oracle 脚本能稳定退出并返回正确状态码”——很多脚本卡在 sqlplus 里没退出,crontab 就堆积进程。
- 必须加
exit在 SQL 脚本末尾,且 shell 中用sqlplus -s /nolog 方式调用,避免 banner 干扰输出 - 检查返回值:
sqlplus成功执行 SQL 返回 0,遇到错误(如权限不足、视图不存在)返回 1,超时或连接失败通常返回 2。别只靠输出内容判断 - 邮件体里务必带上
ORACLE_SID和当前时间,多个实例共用脚本容易混淆告警来源 - 示例片段:
sqlplus -s /nolog <<'EOF' CONNECT / AS SYSDBA SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF SPOOL /tmp/ts_alert_$$.log SELECT tablespace_name || ',' || ROUND(used_space / tablespace_size * 100, 2) FROM V$TABLESPACE_USAGE_METRICS WHERE used_space / tablespace_size > 0.95; SPOOL OFF EXIT EOF if [ $? -ne 0 ]; then echo "SQL execution failed" | mailx -s "[ORA] ts_check fail on $ORACLE_SID" admin@company.com exit 1 fi
为什么刚清理完大表,表空间使用率没降下来
这是最常被误判为“监控异常”的场景。根本原因:Oracle 删除数据只是标记块为可重用,并不自动回收高水位线(HWM),V$TABLESPACE_USAGE_METRICS.USED_SPACE 统计的是已格式化且有段头信息的块,不是“实际数据量”。
- 执行
ALTER TABLE ... SHRINK SPACE COMPACT或MOVE后,才可能降低USED_SPACE - 如果是 TRUNCATE,HWM 会重置,但需等 SMON 清理延迟段(
_cleanup_rollback_entries参数影响速度) - 自动段管理(ASSM)下,空闲空间可能分散在多个 bitmap 块中,
V$TABLESPACE_USAGE_METRICS仍会计为“已用”,直到空间被新对象复用 - 此时告警是合理的——说明空间没真正释放,后续插入仍可能失败,不能因为“数据删了”就忽略
crontab 定时任务要注意哪些Oracle环境变量
绝大多数失败源于 shell 环境和 Oracle 实例环境不一致:cron 默认 PATH 很短,找不到 sqlplus;ORACLE_HOME、ORACLE_SID、PATH 全都没继承。
- 绝对不要在 crontab 里写
0 */2 * * * . ~/.bash_profile; /path/to/check.sh—— cron 不启动 login shell,.bash_profile可能不执行,且不同用户 profile 路径不同 - 正确做法:在脚本开头显式设置:
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1 export ORACLE_SID=orcl export PATH=$ORACLE_HOME/bin:$PATH export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
-
NLS_LANG必须设,否则中文告警内容可能乱码,且某些字符集下sqlplus连接会静默失败 - 测试时用
run-parts --test /etc/cron.hourly或手动模拟 cron 环境:env -i PATH=/bin:/usr/bin $ORACLE_HOME/bin/sqlplus -v
监控表空间增长本身不难,难的是区分“真增长”和“假高位”、让告警不漏不扰、以及脚本在无人值守时持续可靠运行。最容易被跳过的其实是日志留存和告警收敛——同一表空间连续 3 次告警,该合并成一条,而不是每小时刷一封。


















