磁盘物理满时必须立即停用autoextensible,同步检查表空间使用率和挂载点磁盘空间;若df -h显示≥95%且autoextensible='YES',则AUTOEXTEND正导致写爆,须立刻关闭,再迁移数据文件释放压力。

磁盘被占满,不是表空间逻辑满,而是物理空间耗尽——扩容操作本身可能正在把磁盘写爆,必须立刻停止自动扩展并定位源头。
查清是表空间逻辑满还是磁盘物理满
ORA-01653 报错时,dba_free_space 可能显示还有空闲块,但插入仍失败。这不是“空间不够”,而是“磁盘没地方写了”。得同步看两头:
- 查表空间实际使用率:
SELECT tablespace_name, ROUND((total - free)/total*100, 2) AS used_pct FROM (SELECT tablespace_name, SUM(bytes) total FROM dba_data_files GROUP BY tablespace_name) t, (SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name) f WHERE t.tablespace_name = f.tablespace_name - 查对应路径磁盘空间:
df -h /u01/oradata/PROD(路径替换成你dba_data_files.file_name中的真实路径)
如果磁盘使用率 ≥95%,而 dba_data_files.autoextensible = 'YES',那 AUTOEXTEND 正在把磁盘写爆——必须立刻关掉,否则数据库可能 hang 住。
确认哪些数据文件还在自动增长
别只看报错的表空间,要扫全量:所有 autoextensible = 'YES' 且 maxbytes 还没到顶的文件,都可能是“定时炸弹”。
- 执行:
SELECT file_name, bytes/1024/1024/1024 "GB", maxbytes/1024/1024/1024 "MAX_GB", autoextensible FROM dba_data_files WHERE autoextensible = 'YES' AND maxbytes > bytes ORDER BY maxbytes - bytes DESC - 重点看那些
file_name路径落在同一挂载点(比如都指向/u01)且剩余可扩空间大的文件 - 对每个高风险文件,立即执行:
ALTER DATABASE DATAFILE '/path/to/file.dbf' AUTOEXTEND OFF
跳过这步,迁移或 resize 都可能中途失败,甚至引发 ORA-01114。
迁移数据文件释放原磁盘压力
磁盘已满,加文件或 resize 都无效——唯一出路是把部分数据文件物理迁出。Oracle 支持在线迁移,但要求表空间为 ONLINE 状态且数据库为归档模式。
- 先冻结目标文件:
ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/ORCL/users01.dbf' AUTOEXTEND OFF;再RESIZE对齐实际占用(如RESIZE 18G,数值来自HWM计算,不是估算) -
OFFLINE文件:ALTER DATABASE DATAFILE '/u01/.../users01.dbf' OFFLINE - 操作系统层复制(必须用
cp,不是mv)到新挂载点,例如:cp /u01/.../users01.dbf /u02/.../users01_moved.dbf - 数据库内切换路径:
ALTER DATABASE RENAME FILE '/u01/.../users01.dbf' TO '/u02/.../users01_moved.dbf',然后RECOVER DATAFILE+ONLINE
迁移后别忘了更新备份脚本里的路径,并在新路径上谨慎启用 AUTOEXTEND——MAXSIZE 必须小于该磁盘可用空间,且预留 ≥20% 缓冲。
UNDOTBS1 等系统表空间不能 ADD DATAFILE
UNDOTBS1 在 12c+ 多租户之外不支持 ADD DATAFILE,强行执行会报 ORA-30036。这类表空间只能调大现有文件或开 AUTOEXTEND。
- 查当前 UNDO 使用:
SELECT tablespace_name, status, sum(bytes)/1024/1024 FROM dba_undo_extents GROUP BY tablespace_name, status,重点关注ACTIVE和UNEXPIRED占比 - 扩现有文件:
ALTER DATABASE DATAFILE '/u01/.../undotbs01.dbf' RESIZE 2048M或启用扩展:AUTOEXTEND ON NEXT 100M MAXSIZE 4096M - 若长期撑满,优先检查长事务:
SELECT s.sid, s.serial#, s.username, t.used_ublk, t.start_time FROM v$session s, v$transaction t WHERE s.taddr=t.addr AND SYSDATE-t.start_time > 1/24
真正难处理的从来不是命令怎么写,而是搞不清哪一层出了问题:是 SQL 层的段分配、存储层的数据文件、还是 OS 层的磁盘挂载点。三者混在一起报错时,顺序错了,一切操作都是徒劳。


















