ACFS(ASM Cluster File System)是Oracle在ASM基础上构建的集群文件系统,在RAC环境中常用来存放归档日志、Goldengate轨迹文件、备份集等共享数据。很多DBA都熟悉用acfsutil size +10G在线扩容ACFS,但反过来想把ACFS缩小时,却经常遇到各种报错。比如磁盘组空间告急,想把某个闲置的大ACFS卷压缩出几百GB空间给其他磁盘组使用,这时候shrinking操作就成了必须掌握的技能。本文详细讲解ACFS收缩的原理、限制和具体操作步骤。

ACFS收缩的基本原理与前提条件
ACFS文件系统是构建在ASM磁盘组之上的,其空间来自一个ADVM卷设备(例如/dev/asm/volume1-123)。扩容和收缩本质上是调整这个ADVM卷的大小,再联动调整ACFS的逻辑边界。扩容方向几乎无限制,只要磁盘组有空间就行;但收缩方向有严格约束:ACFS只能收缩到未被数据占用的区域,也就是说收缩后的容量必须大于等于当前已使用的空间,否则文件系统的元数据和用户数据会被截断,后果非常严重。
在执行收缩前,有几项前提必须确认。第一,ACFS的元数据版本要满足要求,使用acfsutil version查看驱动版本,建议保持在较新的Patch级别,老版本的ACFS驱动对shrink支持不完善,可能出现收缩后空间统计不一致的问题。第二,确认当前已使用空间,用acfsutil info fs /acfs_mount查看primary storage和used空间,计划收缩后的总容量至少要预留10%到15%的余量,不要刚好卡着used值收缩,否则紧接着写入就会报ENOSPC错误。第三,确认挂载点在所有节点上的状态,收缩属于在线操作,不要求卸载文件系统,但要求各节点ACFS驱动加载正常。
还需要注意一个版本差异:从Oracle 12.2开始,acfsutil的size参数支持负数形式,例如acfsutil size -100G /acfs_mount表示减少100G;而在11.2版本中,不支持负数语法,必须直接指定目标大小,例如acfsutil size 500G /acfs_mount,表示收缩到500G。两种写法效果一样,但命令解析逻辑不同,用错版本语法会直接报参数错误。
ACFS收缩操作完整示例
下面以一个实际场景演示操作。假设挂载点为/backup_acfs,当前总容量2TB,已使用800GB,目标收缩到1TB。先查看文件系统当前状态:
# 查看ACFS文件系统信息 acfsutil info fs /backup_acfs # 输出示例关键信息: # primary volume: /dev/asm/backupvol-123 # total size: 2199023255552 ( 2.00 TB ) # total free: 1533239341056 ( 1.39 TB ) # file system overhead: 8589934592 ( 8.00 GB )
确认空闲空间充足后,执行收缩命令。这里使用12c以后的负数语法,减少1TB:
# 在线收缩,减少1TB,可作用于所有节点 acfsutil size -1T /backup_acfs # 或者直接指定目标大小为1TB(11.2版本推荐写法) acfsutil size 1T /backup_acfs
命令执行过程中,ACFS会先缩小文件系统的逻辑大小,再回收ADVM卷的空间到磁盘组。整个过程在线完成,业务读写不受影响,只是收缩瞬间可能有短暂的IO抖动。执行完毕后再次查看验证:
# 验证收缩结果 acfsutil info fs /backup_acfs # 确认磁盘组空间已归还 asmcmd lsdg -G DATA # Free_MB 字段应明显增加
如果想每次收缩前做安全检查,可以先用df -h /backup_acfs和acfsutil info fs交叉验证used值,两者应基本一致。若发现统计偏差较大,通常是元数据延迟,执行acfsutil defrag fs /backup_acfs整理后再收缩更稳妥。
收缩失败的常见报错与排查
实际操作中最常见的报错是ACFS-03048,提示指定的size无法满足收缩要求。出现这个错误有两种可能:一是目标容量小于当前已使用空间,这是ACFS的安全保护机制,防止数据被截断,处理办法是先清理文件或归档,把used降下来;二是收缩请求与文件系统的内部预留区冲突,ACFS会为元数据保留一定区域,此时可以尝试分多次小步收缩,例如每次减100G,逐步逼近目标值。
另一个典型问题是收缩命令在某个节点执行失败,提示ACFS-02017或ACFS-00543类错误。这类问题多与节点间状态不同步有关,排查步骤是:先用crsctl stat res -t确认ACFS资源在各节点都是ONLINE状态,再检查各节点/dev/asm下的卷设备权限是否一致。如果某个节点的卷设备权限异常,收缩时锁协商就会失败。另外,执行收缩命令不要求在所有节点分别执行,任一挂载节点执行一次即可全局生效,但如果集群通信层(CSS)不稳定,也可能导致命令挂起,此时查看/opt/oracle/diag/log/hostname/acfs.log可以定位原因。
还有一种容易被忽视的情况:收缩成功但磁盘组Free_MB没有增加。这通常是因为ADVM卷空间归还给了磁盘组,但磁盘组的AU分配统计有延迟,或者磁盘组使用了COMPATIBLE.ASM较低版本的属性。确认磁盘组兼容性参数:
-- 检查磁盘组兼容性参数 SELECT name, compatibility, database_compatibility FROM v$asm_diskgroup WHERE name = 'DATA'; -- ACFS相关特性建议 asm compatibility 至少 11.2.0.3 以上 ALTER DISKGROUP DATA SET ATTRIBUTE 'compatible.asm' = '12.2.0.1';
生产环境操作建议
生产环境执行ACFS收缩,建议遵循几个原则。首先选择业务低峰期操作,虽然收缩是在线的,但涉及元数据大量调整,IO抖动在归档写入频繁的系统上可能被放大。其次收缩前做一次信息留存,把acfsutil info fs、df -h、asmcmd lsdg的输出都保存下来,方便事后对比。再者不要一次性收缩到极限,保留15%以上余量,给归档突增和备份脚本临时文件留出缓冲。
对于规划阶段的环境,更推荐一开始就用较小的ACFS容量上线,配合acfsutil size的自动扩展策略:acfsutil size 500G -a 50G /backup_acfs表示初始500G,空间不足时自动增加50G,上限由磁盘组决定。这样既避免过度预分配,又省去人工收缩的风险。ACFS的扩容几乎零风险,收缩则需要谨慎评估,让空间管理尽量往扩容方向倾斜,是更稳妥的运维思路。
Oracle RACACFS文件系统ACFS收缩修改时间:2026-09-03 09:45:08