rman的backup optimization仅跳过未修改的数据文件,不识别hwm下的空闲块,故无法跳过已分配的空块;真正减少空块备份需收缩hwm、使用备份排除或镜像副本分段。
备份集里塞了一堆空闲块,是因为rman默认不跳过已备份过的空闲空间
为什么BACKUP OPTIMIZATION ON不能跳过空闲块
RMAN 的 BACKUP OPTIMIZATION 作用对象是「文件级冗余」,不是「块级内容」。它只判断:这个数据文件自上次备份以来有没有被修改过(通过检查数据文件头的 SCN 和检查点时间戳)。只要文件头没变,哪怕里面新增了 10GB 空闲块、或高水位线以下全是空块,RMAN 仍会把整个文件从头读一遍,把所有分配过的块(包括空块)都写进备份集。
- 空闲块(free blocks)只要还在段的高水位线(HWM)之下,就属于“已分配但未使用”的块,RMAN 不识别其业务语义,一律备份
-
BACKUP OPTIMIZATION对只读表空间、offline 表空间有效,但对在线读写表空间里的空闲块完全无感 - 即使启用了块更改跟踪(BCT),BCT 也只标记“哪些块的 SCN 变了”,不标记“哪些块是空的”——空块的 SCN 仍是旧值,照样被拉进增量备份
真正能减少空闲块写入的配置只有两个
想让备份集体积变小、I/O 减少,得绕开“备份整个数据文件”的逻辑,改用更精细的粒度:
-
BACKUP AS COPY DATABASE配合SECTION SIZE:镜像副本本身不压缩,但可分段跳过 HWM 以上的未格式化区域(需配合ALTER TABLESPACE ... SHRINK SPACE先回收空间) -
BACKUP TABLESPACE+SKIP INACCESSIBLE:虽不直接跳空块,但结合DBMS_SPACE手动识别空段后EXCLUDE,可规避整表空间备份;注意EXCLUDE仅对表空间级备份生效,且要求 RMAN 连接时有SELECT_CATALOG_ROLE - 终极手段:在备份前执行
ALTER TABLE ... SHRINK SPACE COMPACT+ALTER TABLE ... DEALLOCATE UNUSED,物理降低 HWM,让空块彻底退出“已分配”状态——这时BACKUP OPTIMIZATION才有机会体现效果
误以为优化生效的典型现象
很多人看到 CONFIGURE BACKUP OPTIMIZATION ON 后某次备份变快了,其实是巧合:
- 归档日志刚好没产生新文件,
BACKUP ARCHIVELOG ALL DELETE INPUT少扫了几百个日志文件 - 恰好某个大表空间刚被设为
READ ONLY,被BACKUP OPTIMIZATION跳过(这才是它真正起效的场景) - 备份目标路径从 NFS 换成本地 SSD,I/O 延迟下降掩盖了空块读取问题
验证当前备份是否真在写空块
别猜,直接查:
SELECT file#, block# as first_block, blocks, bytes/1024/1024 as mb FROM v$backup_piece_details WHERE piece# = (SELECT MAX(piece#) FROM v$backup_piece) AND file# IN (SELECT file_id FROM dba_data_files WHERE tablespace_name = 'USERS');
再对比对应数据文件的空闲空间:
SELECT file_id, SUM(bytes)/1024/1024 as free_mb FROM dba_free_space WHERE file_id IN (SELECT file_id FROM dba_data_files WHERE tablespace_name = 'USERS') GROUP BY file_id;
如果某文件在 v$backup_piece_details 中占了 50GB,但在 dba_free_space 里只显示 5GB 空闲——说明那 45GB 里至少有大量 HWM 下的“伪空块”,正被 RMAN 忠实地备份着。
空闲块本身不可怕,可怕的是 DBA 把 BACKUP OPTIMIZATION 当成“智能去重开关”。它不看内容,只看文件头;不省空间,只省文件。真要压体积,得动手调 HWM、清段、选对备份类型——而不是反复开关那个开关。











