📢📢📢📣📣📣
作者:IT邦德
中国DBA联盟(ACDU)成员,15年DBA工作经验
Oracle、PostgreSQL ACE
CSDN博客专家及B站知名UP主,全网粉丝15万+
擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复,
安装迁移,性能优化、故障应急处理
凌晨3点报警炸群,某大厂核心数据库突然宕机——罪魁祸首竟是ASM使用率计算误差!90%的DBA都踩过这个坑,今天必须说透。
之前的一个女朋友也是做DBA的,听她说过,某公安系统数据库突发告警:归档进程全线停止!归档日志堆积如山,容灾能力瞬间瘫痪。8小时紧急排查后,根因令人窒息的是FRA磁盘组空间耗尽。但故障前监控显示:磁盘组“剩余空间”竟还有677MB!
这场经典事故撕开了一个行业盲区:ASM的Free_MB指标,可能是最危险的“谎言”。
1.参数解读
1.1 USABLE_FILE_MB
USABLE_FILE_MB表示磁盘故障后可用于新文件恢复冗余的可用空间量,已针对镜像进行了调整。
USABLE_FILE_MB是通过从磁盘组中的总可用空间中减去REQUIRED_MIROR_FREE_MB,然后调整镜像值来计算的。
--for normal redundancy
USABLE_FILE_MB =
(FREE_MB - REQUIRED_MIRROR_FREE_MB)/2
--for high redundancy
USABLE_FILE_MB =FREE_MB - REQUIRED_MIRROR_FREE_MB)/3
但是有时候我们发现USABLE_FILE_MB为负值
1.当FREE_MB < REQUIRED_MIRROR_FREE_MB时,计算后USABLE_FILE_MB为负
2.高冗余(HIGH)需更多预留空间,易因存储不足导致负值
1.2 REQUIRED_MIRROR_FREE_MB
REQUIRED_MIROR_FREE_MB表示磁盘组中必须可用的空间量,以便在磁盘组可以容忍的最严重故障后恢复完全冗余,而无需添加额外的存储。此要求可确保有足够的故障组来恢复冗余。此外,这种最严重的故障是指必须丢弃磁盘的永久性故障,而不是磁盘脱机然后重新联机的情况。
1.3 V$ASM_DISKGROUP
以下是关于Oracle ASM中V$ASM_DISKGROUP视图的字段
2.正确的计算方式
SELECT
name AS diskgroup_name,
type AS redundancy_type,
ROUND(total_mb / 1024, 2) AS total_gb,
ROUND(free_mb / 1024, 2) AS free_gb,
-- 实际已用空间 = 总空间 - 空闲空间
ROUND((total_mb - free_mb) / 1024, 2) AS used_gb,
-- 安全冗余所需保留空间(根据冗余类型动态计算)
required_mirror_free_mb / 1024 AS required_reserve_gb,
-- 实际可用空间(考虑冗余预留)
usable_file_mb / 1024 AS usable_file_gb,
-- 真实使用率(已用空间 / (总空间 - 冗余预留))
CASE
WHEN type = 'EXTERNAL' THEN
ROUND((1 - (free_mb / total_mb)) * 100, 2)
ELSE
ROUND((1 - (usable_file_mb + required_mirror_free_mb) / (total_mb - required_mirror_free_mb)) * 100, 2)
END AS real_usage_pct,
-- 告警状态:若实际可用空间为负或使用率>90%则标记警告
CASE
WHEN usable_file_mb < 0 OR
(CASE WHEN type = 'EXTERNAL' THEN (1 - free_mb/total_mb)
ELSE (1 - (usable_file_mb + required_mirror_free_mb)/(total_mb - required_mirror_free_mb))
END) > 0.9 THEN 'WARNING'
ELSE 'NORMAL'
END AS alert_status
FROM
v$asm_diskgroup
ORDER BY
real_usage_pct DESC;
3.如何释放ASM空间
当数据文件因历史操作(如大表清理、分区归档)产生大量空闲块时,缩小文件可直接释放ASM磁盘组中的物理空间,避免空间浪费。
set verify off
column file_name format a50 word_wrapped
column smallest format 999,990 heading "Smallest|Size|Poss."
column currsize format 999,990 heading "Current|Size"
column savings format 999,990 heading "Poss.|Savings"
break on report
compute sum of savings on report
column value new_val blksize
select value from v$parameter where name = 'db_block_size';
/
select file_name,
ceil( (nvl(hwm,1)*&&blksize)/1024/1024 ) smallest,
ceil( blocks*&&blksize/1024/1024) currsize,
ceil( blocks*&&blksize/1024/1024) -
ceil( (nvl(hwm,1)*&&blksize)/1024/1024 ) savings
from dba_data_files a,
( select file_id, max(block_id+blocks-1) hwm
from dba_extents
group by file_id ) b
where a.file_id = b.file_id(+) order by savings desc
/
alter
database
datafile '/oracle/app/oradata/ORCL/data01.dbf'
resize 3800M;
如果低于HWM,则会出现以下报错
ORA-03297: file contains used data beyond requested RESIZE value
结语
“监控Free_MB的DBA在救火,盯住Usable_file_MB的DBA在喝茶”
真正的空间战争,从认清冗余镜像的代价开始。下次查看ASM使用率时,请记住:那个看似宽裕的数字,可能正掐住数据库的咽喉。