DBAtlas · 数据库运维图谱

磁盘/表空间已满

出现了 'unable to extend'、'disk full'、'could not extend' 或 'log full'。不要慌:先找出是什么满了,安全地回收空间,再做永久修复。

什么满了?

清理错了地方无济于事。先测量使用情况:是数据文件、事务日志、归档/redo、temp,还是操作系统磁盘?

SELECT d.tablespace_name, ROUND((1-(d.alloc-NVL(f.free,0))/d.maxb)*100,1) AS pct_free
FROM (SELECT tablespace_name, SUM(bytes) alloc, SUM(GREATEST(bytes,maxbytes)) maxb FROM dba_data_files GROUP BY tablespace_name) d LEFT JOIN (SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name) f ON f.tablespace_name = d.tablespace_name ORDER BY pct_free;
  • 数据文件/表空间已满
  • 事务日志/归档-redo 已满
  • temp/undo 已满
  • 操作系统磁盘已满(不是数据库)

最大的占用者是什么?

大多数情况下罪魁祸首是某一个失控的表/段。找出最大的那些。

SELECT segment_name, segment_type, ROUND(bytes/1048576,1) AS mb FROM dba_segments ORDER BY bytes DESC FETCH FIRST 10 ROWS ONLY;
  • 有一个意外巨大/失控的表
  • 正常增长,空间确实用完了
  • 死行过多/膨胀(bloat)

日志为什么在增长?

在最老的活动事务/备份完成之前,日志/归档无法清理。它为什么会累积?

SELECT name, log_reuse_wait_desc FROM sys.databases WHERE name=DB_NAME();  -- why can it not be truncated?
  • MSSQL:没有执行日志备份(LOG_BACKUP)
  • PG:停滞的复制槽保留着 WAL
  • Oracle:归档日志区(FRA)已满
  • 长时间打开的事务占住了日志

根本原因:失控的表/段

某个对象意外增长(不受控的插入、从未清理的队列/日志表)。

根本原因:确实需要扩容

正常增长;必须增加空间。

根本原因:膨胀/死行

已删除/更新的行所占空间未被回收。

根本原因:temp/undo 已满

大型排序/哈希或长时间打开的事务占满了临时空间。

根本原因:操作系统磁盘已满

问题出在操作系统磁盘上,而不是数据库。日志、core dump、旧备份或跟踪文件可能占用了空间。

根本原因:未执行日志备份(SQL Server)

在 FULL 恢复模式下,若不执行日志备份,日志会无限增长。

根本原因:被遗弃的复制槽(PG)

停滞(非活动)的复制槽会阻止 WAL 被删除,并撑大 pg_wal。

根本原因:归档日志区(FRA)已满(Oracle)

归档日志累积导致 FRA 已满;归档进程一旦停滞,数据库可能停止接受写入。

根本原因:长时间打开的事务

最老的活动事务阻止了日志/undo 被回收。

在 DBAtlas 中打开 →