恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Oracle ASM磁盘组空间计算:普通冗余下可用容量与ORA-15041排查指南
首页
资讯中心
/
Oracle ASM磁盘组空间计算:普通冗余下可用容量与ORA-15041排查指南
Oracle ASM磁盘组空间计算:普通冗余下可用容量与ORA-15041排查指南
发布时间:2026/10/16 7:37:42
最近在一个生产环境里遇到一个挺典型的Oracle ASM问题磁盘组监控显示还剩几百GB可用但业务侧创建数据文件就是报ORA-15041DBA现场一脸懵。后来排查下来问题不在磁盘“有没有空间”而在大家对ASM磁盘组的空间分配逻辑理解不一致——尤其是普通冗余和故障组机制下“物理剩余空间”和“实际可写入空间”根本是两码事。这篇文章我想把Oracle ASM磁盘组的空间分配模型、冗余机制和动手计算方法完整梳理一遍。不管是刚接触ASM的初学者还是已经被ORA-15041坑过的运维老手只要你需要规划磁盘组、扩容数据盘、判断“到底还能不能加文件”这篇内容应该都能给你一个比较清晰的参考。我会先讲ASM底层的存储模型再讲冗余策略对空间的真实影响然后给出实际可用的估算方法最后聊几个我在巡检和扩容中反复踩过的坑。1. 磁盘组空间为什么经常“不够用”从一次ORA-15041说起1.1 告警场景那个现场是这样的一套双节点集群DATA磁盘组类型是NORMAL REDUNDANCY由12块1TB的物理盘组成两个故障组各6块盘。监控面板上Free_MB还有六七百GB结果应用在跑一个大批量插入的时候临时表空间自动扩展直接失败报错码就是ORA-15041。当时第一反应是磁盘真的满了但看裸容量确实还有剩余于是开始怀疑是ASM元数据问题甚至有人提议去清理归档日志。后来查了V$ASM_DISKGROUP才发现Usable_file_MB已经非常接近0。也就是说ASM视角下的“可用文件空间”早就耗尽只是物理层面的Free_MB还没归零。这个差异本质上就是冗余镜像所占用的那部分空间在“作祟”。1.2 问题本质自由空间和可写入空间不是一回事普通冗余下每一份数据extent都会被ASM复制成两个镜像副本分别放在不同的故障组里。这意味着当你看到磁盘组有100GB的空闲容量时ASM并不能把这100GB全部拿去做“一份数据”的存储它至少要预留一半的容量用来放镜像副本。所以你真正能往里写入的“有效数据量”在NORMAL冗余下通常只有物理空闲空间的一半左右在HIGH冗余下则是1/3。这个比例和文件系统比如ext4或者XFS完全不同——文件系统看到100GB剩余就能写100GBASM则必须先扣掉镜像复制带来的开销。这也是很多DBA第一次接触ASM时最容易产生认知偏差的地方。除此之外ASM的可用空间还受故障组之间的容量平衡影响。如果两个故障组大小不一致容量较小的故障组会成为写入瓶颈物理剩余空间再多真正可用的数据容量也会被“短板”拖住。下面几节我会把AU、Extent、故障组这些概念逐一拆开讲然后再回到空间计算这件事上。2. ASM的基本存储单元AU、Extent和故障组ASM不是简单地把磁盘格式化成文件系统它的核心是把多个物理磁盘聚合成一个逻辑存储池然后再按固定大小的“分配单元”去管理数据。理解这三个概念是搞懂空间分配的前提。2.1 AU分配的基本单位AUAllocation Unit是ASM分配空间的最小单位。在Oracle 11g中新建磁盘组的默认AU大小是1MBOracle 12c及之后版本默认是4MB。AU越大单个磁盘组能够支撑的存储上限越高因为ASM的数据区描述能力是有限的但AU越大小文件写入时的空间浪费也越明显。你可以把AU想象成一个大楼里的标准车位无论停什么车都必须占一个完整的车位。ASM给任何文件分配空间时最少给一个AU文件增长时也是一块块AU叠加。对于数据文件这类连续写入的负载1MB或4MB的粒度影响有限但如果你在ASM上存了大量几十KB的小文件AU的浪费就会变得可观。查看当前磁盘组的AU大小很简单SELECT name, allocation_unit_size, state, type FROM v$asm_diskgroup;2.2 Extent带冗余的分配单位文件在ASM里不是直接跟AU打交道的而是通过“Extent”这个逻辑单位。一个Extent对应一个或多个AU具体对应关系会随着文件大小增长而变化。早期文件分配的Extent比较小比如1个Extent等于1个AU当文件已经分配了一定规模的Extent后后续的Extent会变成8个AU甚至64个AU。这种变长Extent设计的目的是减少大规模文件的元数据数量。如果一个1TB的数据文件全部用1MB的Extent来管理那就得有上百万条空间映射记录那是不可接受的用64MB甚至更大的Extent去覆盖文件尾部的大量空间元数据量就小得多。正是因为ASM以Extent为粒度做镜像和管理而不是像传统RAID那样以整个条带或整块磁盘为粒度ASM才能做到把一份数据的多个副本灵活分布到不同故障组从而在故障隔离上获得更大的自由度。2.3 故障组镜像放置的逻辑边界故障组Failure Group是ASM里最容易理解错的概念。它不是物理硬盘本身而是一个“可能同时失效的磁盘集合”。在普通冗余下一份Extent的镜像绝对不能放在同一个故障组里在高冗余下三份副本必须跨三个故障组。最常见的故障组划分方式是按存储柜或HBA卡来分。比如一台服务器挂了两个磁盘柜每个柜6块盘那么你可以把第一个柜的6块盘设成FG1第二个柜的6块盘设成FG2。这样即使其中一个存储柜整体断电ASM仍然能通过另一个柜上的副本继续提供服务。这里有个关键点故障组不是RAID组也不是磁盘组内简单的“盘分组”。ASM在做镜像放置时会优先选择不同故障组内的磁盘从而保证容灾逻辑是围绕“故障域”而不是“单块磁盘”来设计的。这一点也直接决定了磁盘组的空间利用率——如果两个故障组容量不均衡低容量的故障组就会限制整个磁盘组的可用空间。3. 三种冗余策略到底怎么吃空间Oracle ASM一共支持三种冗余类型外部冗余、普通冗余、高冗余。它们的目标都是保证数据不因磁盘故障而丢失但空间代价和逻辑复杂程度差异很大。3.1 外部冗余最省空间但不是ASM在做保护外部冗余EXTERNAL REDUNDANCY模式下ASM不复制任何数据副本一份数据只写一份磁盘组的可用空间约等于物理容量总和。但ASM也不会帮你做任何磁盘故障恢复它的前提假设是“底层存储已经做了RAID保护”。比如你在存储阵列上做了RAID10然后把LUN直接交给ASM这时再让ASM做镜像就是双重浪费。外部冗余很适合这种场景。它的可用率最高、性能开销最小但代价是ASM本身失去了跨物理盘的故障恢复能力一旦底层存储真的坏了ASM只能看着磁盘组脱机。很多初学ASM的人会踩一个坑图省事把所有磁盘组都建成外部冗余却没确认底层存储是否真的具备足够的可靠性。等到底层一块盘故障、数据无法恢复时再回头怪ASM“不给力”其实从设计之初就已经埋下了隐患。3.2 普通冗余两路镜像的空间账普通冗余NORMAL REDUNDANCY是数据库环境中最常见的类型。每个数据Extent都会保存两份一份是主副本一份是镜像副本且两份副本必须在不同的故障组。这带来两个直接后果第一可用空间大幅缩水。理论上正常冗余下磁盘组的可用空间约等于物理容量的1/2。注意这只是理论值实际还要受故障组容量平衡约束。第二故障容忍能力提升。只要不是同一份数据的两个副本同时损坏ASM都能继续工作即使一个故障组整体脱机另一个故障组仍保留完整数据。用生活里的例子来说普通冗余就像你给重要文件做了两份拷贝分别存放在两个安全屋。每个安全屋都能独立撑起整套数据但你实际能存的新文件数量最多只有两个安全屋总容量的一半。因为每份新文件都要在两个安全屋里各占一份空间。3.3 高冗余三副本的适用场景高冗余HIGH REDUNDANCY要求数据有三份副本分别放在至少三个故障组里可用空间进一步下降到物理容量的1/3。它是三种模式中容错能力最强的能容忍两个故障组同时失效。在大多数OLTP生产环境里高冗余并不常见因为它牺牲了太多存储容量。通常只有在跨机房、跨存储阵列、且对RPO要求极高的场景下才会考虑。而且要注意ASM对高冗余的故障组数量有硬性要求至少三个故障组。有些人在两个故障组里硬建HIGH磁盘组直接报错。3.4 冗余与容错能力的对照下面这个表可以比较直观地展示三种冗余的差异冗余类型数据副本数最少故障组数理论可用空间容错能力外部冗余11约等于物理容量不能容忍ASM盘故障普通冗余22约等于物理容量的一半容忍一个故障组失效高冗余33约等于物理容量的1/3容忍两个故障组失效需要强调“理论可用空间”只是估算。实际生产环境里空间使用率不会真的顶到50%或33%因为磁盘组还需要留出一部分余量给日常写入、临时排序和rebalance操作。4. 磁盘组可用空间的计算与常见误区很多人问我到底怎么看磁盘组还剩多少空间最直接的方法是看V$ASM_DISKGROUP里的Usable_file_MB字段它已经考虑了冗余因子表达的是“当前还能容纳多少份有效数据”。也可以用asmcmd lsdg查看输出里同样有Usable_file_MB列。4.1 利用V$ASM_DISKGROUP和asmcmd算真正可用空间下面的SQL可以快速看到每个磁盘组的冗余类型、物理总容量、物理剩余空间以及带冗余之后的有效可用空间SELECT name, type, total_mb, free_mb, usable_file_mb, offline_disks FROM v$asm_diskgroup;如果你习惯于命令行进入ASM实例后执行asmcmd lsdg输出结果里有几个字段需要重点看。Free_MB是物理层面的剩余空间Usable_file_MB是考虑了冗余镜像后的可写入空间两者的关系大致是Usable_file_MB约等于Free_MB除以镜像份数。外部冗余因为是单副本基本相等普通冗余约等于1/2高冗余约等于1/3。这也是那个生产现场的关键所在Free_MB看起来还有六七百GB但除以2之后有效可用空间只剩三四百GB再扣掉ASM预留和PTF开销实际已接近临界值大事务一冲就撞上ORA-15041。4.2 一个手工估算的思路如果你在规划阶段还没有创建磁盘组可以用一个估算思路来粗算可用空间。假设物理磁盘总容量为T冗余镜像份数为R故障组数量为N那么在故障组容量完全均衡的理想情况下可用空间 ≈ T / R但在故障组容量不均时需要进一步取短板。比如普通冗余下有两个故障组容量分别为A和B假设A B那么可靠可用空间更接近A × 2还是A取决于你如何评估容灾目标。如果要求任意一个故障组失效后数据不丢、服务不停那么有效可用容量上限其实会被较小的故障组卡住因为所有镜像对的一半必须落在小故障组里。这也就是ASM空间规划中“木桶效应”的由来。举例故障组1有5TB故障组2有4TB普通冗余下理论总物理容量9TB但真正能安全写入的数据量更接近4TB左右而不是9/24.5TB。多出来的那0.5TB在故障组失效时是救不了命的。4.3 磁盘大小不均为什么特别吃亏很多扩容动作都是在磁盘组里“贴一块盘”。比如原来12块盘都是1TB最近空间紧张加了一块2TB的盘进故障组1。结果你会发现磁盘组物理容量增加了但可用空间并没有等比例增加因为故障组2的总容量没变镜像的“短板”反而被拉得更明显。所以我一直建议ASM磁盘组内的磁盘大小和故障组容量一定要尽量保持一致。如果实在做不到至少要保证各故障组的总容量在同一水平线上。否则你花真金白银买的容量很大一部分会被冗余机制变成永远用不上的“镜像死角”。4.4 rebalance和故障恢复还要占空间还有一个容易被忽略的空间消耗者rebalance。当你往磁盘组里增加磁盘、移除磁盘或者修改磁盘组的冗余属性时ASM会触发重新平衡操作把现有数据extent重新分布到所有磁盘上。这个过程中的数据搬移不是瞬间完成的ASM需要额外的空间作为“中转站”。如果磁盘组的可用空间已经非常紧张rebalance可能根本跑不动甚至失败。这就陷入了一个恶性循环空间不足所以扩容扩容触发rebalancerebalance又因为空间不足而卡住。因此日常使用中我建议把磁盘组的空间水位控制在有效容量的75%以内最多不超过80%。留出的这部分空间既为正常的写入抖动提供了缓冲也为rebalance和故障副本重建留了余地。很多ORA-15041并不是“完全满了”才触发而是在水位过高、ASM判断没有足够安全余量时就拒绝分配了。5. 扩容、建组与日常监控的实操建议说了这么多原理最后落回实战。下面是我在规划磁盘组、扩容以及日常巡检中比较常用的一些做法供参考。5.1 创建磁盘组时的冗余规划新建磁盘组时先想清楚底层存储已经提供了什么级别的保护。如果底层是RAID10或RAID5并且你能够接受“整台存储柜故障”这种极端情况通常会选外部冗余加故障组规划如果底层就是普通磁盘没有额外RAID保护那就必须用普通冗余或高冗余。创建普通冗余磁盘组时至少要规划两个故障组并且两个故障组的总容量要接近。一个比较稳的创建方式是在SQL里显式指定故障组CREATE DISKGROUP data NEW NORMAL REDUNDANCY FAILGROUP fg1 DISK /dev/asm/data01 NAME data01, /dev/asm/data02 NAME data02, /dev/asm/data03 NAME data03 FAILGROUP fg2 DISK /dev/asm/data04 NAME data04, /dev/asm/data05 NAME data05, /dev/asm/data06 NAME data06;创建后立即用asmcmd lsdg确认每个故障组的容量是否均衡。如果发现某一边明显偏大或偏小趁数据还少、rebalance成本低的时候及时调整远比日后迁移划算。5.2 扩容前先算Three-way空间账扩容时不要只看“加了几块盘、物理空间增加了多少”。我习惯这样算账先记录当前磁盘组的Usable_file_MB再估算新盘加入后各故障组的总容量变化最后按镜像份数折算有效增加量。举个例子。一个NORMAL冗余磁盘组FG1当前5TB、FG2当前5TB接近满载。现在只有一块2TB盘可以加。如果加到FG1FG1变成7TBFG2还是5TB短板不变有效可用容量不会有实质提升。正确做法是至少同时为FG1和FG2各增加等量容量或者两块盘分别放进两个故障组才能让有效空间真正增加。这个计算并不复杂但很多扩容事故恰恰是因为只看了物理容量增长没有站在“木桶效应”和镜像开销的角度去思考。5.3 日常监控里我习惯盯的几个指标除了常规的Total_MB、Free_MB我会额外盯三个指标。第一个是Usable_file_MB这是带冗余后的有效剩余空间比Free_MB更能反映真实容量压力。第二个是Offline_disks只要有磁盘处于离线状态整个磁盘组的可用空间会因为缺少冗余副本而进一步下降。第三个是REBALANCE状态如果长时间处于RUNNING要关注是不是空间不足导致的数据搬移停滞。再补充一个小小的经验每当磁盘组可用空间接近20%时我就会主动检查是否有无效RMAN备份、过期归档、超大日志文件等可以清理的对象。与其等到ORA-15041打爆应用不如让空间水位始终处于可控区间。最后说一点个人的体会。ASM空间管理从原理上看并不复杂真正容易出问题的地方往往是你把一个“文件系统思维”带到了ASM里。文件系统里剩余空间就是可写空间ASM里还要叠加冗余、故障组、rebalance这些变量。只要你在建组时把故障组容量规划均衡、平时监控带冗余后的有效可用空间、扩容前先算清楚短板在哪绝大多数空间相关的坑都是可以提前避开的。遇到ORA-15041也别急着清数据先看一眼Usable_file_MB和故障组分布答案通常就在那里。