Linux查看文件大小,du和df命令区别

前言

排查磁盘满时最容易混淆 du 和 df:一个统计文件实际占用,一个统计分区已用空间,二者数字常常对不上。搞清楚各自口径、配合使用,才能准确找到占空间的目录和被已删除但仍被进程占用的空间。本篇讲清两者区别、常用参数和排查组合拳。

一、df:看分区(文件系统)整体用量

df 读取文件系统超级块,统计每个分区总容量、已用、可用、挂载点,回答的是"这块盘还剩多少"。

# 人类可读格式(K/M/G),显示文件系统类型
df -hT
# 只看某个挂载点
df -h /var
# 列出 inode 使用情况(空间没满但报 No space 时排查)
df -i

参数:-h 人类可读,-T 显示类型,-i 查看 inode,-x tmpfs 排除内存临时文件系统。

二、du:统计目录/文件实际占用

du 遍历目录树累加每个文件大小,回答的是"哪个目录最占地方"。

# 查看当前目录大小,人类可读
du -sh .
# 查看 /var 下一级子目录大小并排序(从大到小)
du -h --max-depth=1 /var | sort -rh | head -20
# 查看单个文件大小
du -h /var/log/messages
# 统计当前目录下各子目录,只显示总计
du -sh /var/*

参数:-s 只显示汇总,-h 人类可读,--max-depth=N 限定统计层级,-x 不统计其他挂载点。

三、两者核心区别

对比项 df du
统计对象 文件系统分区整体 目录/文件实际大小
数据来源 超级块分配/使用记录 遍历文件累加
回答问题 盘还剩多少 哪个目录占空间
典型用途 判断是否磁盘满、inode 耗尽 定位大目录、大文件

四、为什么 du 和 df 数字对不上

常见三种原因:

  1. 已删除文件仍被进程占用:文件删掉了但进程没释放句柄,du 不再统计,df 仍计入已用。用 lsof | grep deleted 找到占用进程,重启或截断对应文件即可释放。
  2. 硬链接重复统计口径:du 按目录累加,硬链接在不同目录可能被重复计数;df 看块设备分配更准。
  3. 隐藏在挂载点下的旧文件:目录里先写了数据,后在该路径挂载新盘,旧文件被遮盖,du 看不到,df 上一层分区仍占用。

五、磁盘满排查标准流程

# 1. 先用 df 确认哪个分区满了、inode 是否耗尽
df -h
df -i
# 2. 进入对应分区,逐层 du 找大目录
du -h --max-depth=1 /var | sort -rh | head
# 3. 找大于 500M 的文件
find /var -type f -size +500M -exec ls -lh {} \;
# 4. 检查被删除但仍占用空间的文件
lsof | grep deleted

定位到日志、缓存、旧备份等大文件后,优先归档或压缩,不要直接 rm 正在被写入的日志,应截断:

# 清空正在写入的日志而不释放句柄冲突
> /var/log/nginx/access.log

六、常见坑

  1. 只 du 不 df:看完目录不大,却忽略分区已 100%;
  2. du -sh / 统计到其他挂载点:加 -x 限定当前文件系统;
  3. 误删正在写入的大日志:空间不释放,应先重启对应服务或用 > 截断;
  4. 只看磁盘空间忽略 inode:小文件过多时空间有剩但创建文件失败,用 df -i 排查;
  5. 权限不足漏统计:普通用户 du 部分目录读不到,排查时用 root。

总结

df -h 看分区用量和剩余,du -sh --max-depth=1 目录 逐层定位大目录;两者数字不一致时优先怀疑"已删除但被进程占用"的文件,用 lsof | grep deleted 核对。排查顺序:先 df 定位分区,再 du 找目录,最后 find 找具体大文件。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-22 07:33 

Linux查看目录占用

Linux查看目录占用

引言

磁盘满了先定位是哪个目录吃掉空间,df看整体分区,du逐层下钻找大户。两个命令配合,从分区到目录到文件逐级缩小范围,是磁盘排查的标准路径。

看整体分区:df

df -h

人类可读格式显示各分区总量、已用、可用、使用率,先判断是哪个挂载点满了。

看单个目录总大小

du -sh /var/log

-s汇总,-h人类可读,直接给出这个目录总共占多大。

看一级子目录大小并排序

du -h --max-depth=1 /var | sort -rh | head

只算一层子目录,sort -rh按人类可读大小倒序,head取前几名,快速定位大户。

常用简写

du -sh /var/*

列出/var下每个一级目录大小,逐层进入继续排查。

排除文件系统统计

du -shx /home

-x不跨文件系统,避免把挂载的别的盘也算进来。

看目录下文件数量

ls /var/log | wc -l

有些目录不大但文件海量,inode耗尽也会写不进,配合df -i看inode。

注意事项

  • df看分区,du看目录,先df定位再du下钻;
  • 大目录du会遍历较慢,加--max-depth限制层数;
  • 删除大文件后空间没释放,可能是进程仍持有句柄,需重启进程;
  • sort -rh依赖du输出的G/M单位;
  • /proc、/sys是虚拟文件系统,du统计无意义;
  • 日志目录优先排查,常是增长最快的大户。

总结

df -h看分区整体,du -sh看单目录汇总,--max-depth=1配合sort -rh找一级大户,-x不跨文件系统,ls加wc -l看文件数,df -i查inode。排查路径是先df定位满的分区,再du逐层下钻,删文件后空间不释放要查持有句柄的进程,日志目录优先检查。


emer 发布于  2026-10-20 07:14 

MySQL查看数据库大小,表占用空间

前言

磁盘快满了,不知道哪个库哪个表占空间大。本文教你查MySQL数据库和表的大小。

一、查看所有数据库大小

SELECT 
    table_schema AS '数据库名',
    ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;

输出:

数据库名 大小(MB)
mydb 512.34
test 128.56
mysql 10.24

二、查看某个数据库的所有表大小

SELECT 
    table_name AS '表名',
    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)',
    table_rows AS '行数'
FROM information_schema.tables
WHERE table_schema = 'mydb'
ORDER BY (data_length + index_length) DESC;

把 mydb 换成你的数据库名。

三、查看单个表大小

SELECT 
    table_name AS '表名',
    ROUND((data_length) / 1024 / 1024, 2) AS '数据大小(MB)',
    ROUND((index_length) / 1024 / 1024, 2) AS '索引大小(MB)',
    table_rows AS '行数'
FROM information_schema.tables
WHERE table_schema = 'mydb' AND table_name = 'users';

四、查看所有表大小(按大小排序)

SELECT 
    table_schema AS '数据库',
    table_name AS '表名',
    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)',
    table_rows AS '行数'
FROM information_schema.tables
ORDER BY (data_length + index_length) DESC
LIMIT 20;

只看前20大的表。

五、用命令行查看

查看数据目录

du -sh /var/lib/mysql/

查看某个库的大小

du -sh /var/lib/mysql/mydb/

查看所有库的大小

du -sh /var/lib/mysql/*/

六、常用场景

场景1:磁盘满了,找大表

SELECT 
    table_schema AS '数据库',
    table_name AS '表名',
    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)'
FROM information_schema.tables
ORDER BY (data_length + index_length) DESC
LIMIT 10;

找出最大的10个表。

场景2:表很大,想知道数据和索引各占多少

SELECT 
    table_name AS '表名',
    ROUND(data_length / 1024 / 1024, 2) AS '数据(MB)',
    ROUND(index_length / 1024 / 1024, 2) AS '索引(MB)'
FROM information_schema.tables
WHERE table_schema = 'mydb';

场景3:清理无用数据,释放空间

删了很多数据,但磁盘空间没释放。

原因: InnoDB删数据后不会自动释放磁盘空间。

解决: 优化表:

OPTIMIZE TABLE users;

常见坑

坑1:table_rows不准

InnoDB的table_rows是估算值,不是精确值。

原因: InnoDB是多版本的,统计信息不精确。

解决: 要精确行数用 SELECT COUNT(*) FROM 表名;

坑2:删了数据空间没释放

DELETE删了很多行,但文件大小没变。

原因: InnoDB的表空间不会自动收缩。

解决: OPTIMIZE TABLE 表名; 或者重建表。

坑3:临时表占空间

performance_schema等系统库也占空间。

解决: 正常现象,不用管。

坑4:ibdata1文件很大

共享表空间文件很大,但不知道里面是什么。

原因: 所有InnoDB表都存在一个文件里。

解决: 开 innodb_file_per_table,每个表独立文件。

总结

常用查询:

  1. 查所有库大小:GROUP BY table_schema
  2. 查某库所有表:WHERE table_schema='库名'
  3. 查某表大小:WHERE table_schema='库名' AND table_name='表名'

记住: 磁盘满了先查information_schema.tables找大表。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:49 

Linux磁盘占用100%怎么排查,大文件查找清理方法

前言

服务器跑着跑着突然网站打不开了,SSH 也反应变慢,一查磁盘使用率 100%。这是运维中非常常见的问题。磁盘满了不仅影响服务正常运行,还可能导致数据丢失、日志写不进去等严重后果。本文就手把手教你怎么快速定位磁盘占用大的文件,以及怎么安全清理。

第一步:查看整体磁盘使用情况

先用 df 命令看看哪个分区满了:

df -h

参数说明:

  • -h:以人类可读的方式显示(G、M)

输出示例:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   38G  2.0G  95% /
devtmpfs        7.8G     0  7.8G   0% /dev
tmpfs           7.8G     0  7.8G   0% /dev/shm
tmpfs           7.8G  480M  7.8G   6% /run
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup

看 Use% 那一列,如果哪个分区到了 100% 或者 90% 以上,那就是问题所在。比如上面 /dev/vda1 用了 95%,根分区快满了。

第二步:定位哪个目录占用最大

知道哪个分区满了,接下来找是哪个目录占了最多空间。用 du 命令:

1. 查看根目录下各目录的大小

du -sh /* 2>/dev/null

参数说明:

  • -s:只显示总计,不显示每个子目录
  • -h:人类可读格式
  • 2>/dev/null:忽略权限不足的报错信息

输出示例:

0       /bin
100M    /boot
...
15G     /home
20G     /var
3G      /usr

从输出可以看出 /var 目录占了 20G,是大头。

2. 继续往下查 /var 目录

du -sh /var/* 2>/dev/null | sort -rh | head -10

参数说明:

  • sort -rh:按大小倒序排列
  • head -10:只显示前10个最大的

输出示例:

15G     /var/log
3G      /var/lib
1G      /var/cache
...

继续往下查,直到找到具体是哪个文件最大。

第三步:查找最大的单个文件

如果目录太大不好定位,直接找整个系统里最大的文件:

1. 查找大于100M的文件

find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}'

参数说明:

  • -type f:只找文件,不找目录
  • -size +100M:找大于100M的文件
  • 2>/dev/null:忽略权限报错

2. 按大小排序显示前20个最大文件

find / -type f -size +10M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh | head -20

这样就能列出系统里最大的20个文件,一目了然。

常见的磁盘占用大户

根据经验,Linux 磁盘占用大通常是这几个地方:

1. 日志文件(/var/log)

这是最常见的。服务跑久了日志文件会越来越大,尤其是:

  • Nginx 访问日志、错误日志
  • MySQL 慢查询日志、错误日志
  • 系统日志 messages、syslog

排查方法:

du -sh /var/log/* | sort -rh | head -10

2. 已删除但仍被进程占用的文件

有时候你删掉了大文件,但磁盘空间没释放,因为还有进程在占用这个文件的句柄。

排查方法:

lsof | grep deleted

如果看到很多 deleted 状态的文件,说明有进程占用着已删除的文件。重启对应的进程就能释放空间。

3. 缓存文件(/var/cache)

yum 下载的缓存包、APT 的缓存都在这里,时间久了会积累很多。

清理方法:

yum clean all

4. Docker 镜像和容器

如果用了 Docker,镜像、容器、日志都会占很多空间。

排查方法:

docker system df

清理方法:

docker system prune -a

安全清理方法

找到大文件后,不要直接 rm -rf 删了就完事,要注意安全:

1. 日志文件:清空而不是删除

如果是日志文件,不要删文件本身,而是清空内容:

> /var/log/nginx/access.log

或者:

echo "" > /var/log/nginx/access.log

这样文件还在,但内容清空了,不会影响正在写入的进程。

2. 大文件:先确认再删除

删之前一定要确认这个文件是不是真的不需要了:

ls -lh /path/to/file
head -20 /path/to/file  # 看看内容是什么

确认没问题再删:

rm -f /path/to/file

3. 已删除但被占用的文件

如果删掉文件后空间没释放,找到占用的进程并重启:

lsof | grep deleted
# 找到对应的 PID,重启服务
systemctl restart nginx

常见坑

坑1:用 du 查到的大小和 df 不一致

有时候 df 显示磁盘满了,但 du -sh /* 加起来远没到那个数。这通常是因为:

  • 有已删除但仍被进程占用的文件
  • 挂载点下还有其他挂载

解决: 用 lsof | grep deleted 找被占用的已删除文件,重启对应进程释放空间。

坑2:删了文件空间没释放

这就是上面说的坑——文件被进程占用着,虽然删了但空间没释放。必须重启进程才能释放。

坑3:直接删日志文件导致服务异常

很多人直接 rm -f /var/log/nginx/access.log,结果 Nginx 还在往这个已经不存在的文件里写,日志就丢了。正确做法是清空内容而不是删除文件:> /var/log/nginx/access.log。

总结

排查磁盘占用的标准流程:

  1. df -h 看哪个分区满了
  2. du -sh /* | sort -rh 找最大的目录
  3. find / -type f -size +100M 找最大的文件
  4. 确认文件用途后再清理
  5. 日志文件清空内容,不要直接删文件

日常运维建议配置 logrotate 自动切割日志,避免日志越积越大。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:26 
'); })();