searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

删除操作成功后,磁盘空间没释放?—磁盘幽灵

2025-08-22 06:17:04
1
0

第一章:MySQL假删除困局

深夜11点,运维工程师小明收到数据库服务器磁盘告警:空间使用率95%!分析发现BIG_TABLE表的2年前日志是元凶。他果断执行清理:

DELETE FROM BIG_TABLE WHERE create_time < '2023-01-01';  -- 删除12亿条历史日志   

确认事务提交后,监控显示表数据已消失。但次日清晨,服务器磁盘爆满,数据库陷入瘫痪——空间竟丝毫未释放!

分析:

InnoDB标记删除机制下,DELETE操作仅将数据标记为逻辑删除(打上删除标签),物理数据仍占据磁盘目的是支持MVCC(多版本并发控制),保证事务隔离性

空间归属权上,InnoDB不会主动将空间归还OS,仅允许新数据复用原有空间

释放方案

-- 彻底释放空间

OPTIMIZE TABLE BIG_TABLE;  -- 重建表消除碎片

第二章:Linux僵尸文件之谜

一周后,小明再遇磁盘告警!Apache日志文件access.log已增长至40GB。他火速执行:

bash

rm /var/log/apache/access.log  # 删除日志文件  

ls -l /var/log/apache/        # 确认文件消失  

然而两小时后,业务系统崩溃——磁盘空间依然耗尽!

分析:

inode引用计数器:

rm仅删除文件路径(目录项),inode引用数减1

Apache进程仍持有文件句柄,引用计数>0

空间持有者实锤:

lsof | grep deleted  # 关键命令揪出"僵尸文件"  

apache2 14836 root 1w REG 254,0 42G 65536 /var/log/apache/access.log (deleted)  

   如果一个进程在 rm 之前就已经打开了文件 A,那么它手里就握着一个指向该文件 inode 的文件描述符(File Descriptor)。 内核会为所有打开的文件维护一个引用计数器。只要还有进程持有文件描述符,即使目录中的链接已经被删除(link count = 0),内核也不会立即释放该文件的数据块,因为进程可能还要进行读写操作。此时,这个文件就变成了一个你看不到它,但它却真实存在的文件。这种设计是非常合理和安全的1保证进程稳定性:确保正在使用文件的程序不会突然因为文件被删除而崩溃或出错。2允许文件无缝替换:例如,日志文件可以被 rm 掉然后重新创建,而正在写入的进程可以毫不知情地继续向原来的文件描述符写入,新的数据会写到新创建的文件中

释放方案

# 方案1:优雅重启释放句柄 ,重启进程

kill -HUP 14836    # 通知Apache重建日志文件([网页12])  

# 方案2:清空文件立即释放空间,进程不能重启的情况下的选择 

echo "" > /proc/14836/fd/1  # 通过进程文件描述符清空  

最终启示录

删除 释放!

在计算机的世界里,可见的删除只是表象,空间的释放才是终极奥义。经验不足的同学,执行完删除操作可能就完事了,较有经验的同学会DOUBLE CHECK,确保删除真正生效。但经验丰富的同学,会用du命令检查空间的释放,提前发现问题。

0条评论
0 / 1000
陈****关
1文章数
0粉丝数
陈****关
1 文章 | 0 粉丝
陈****关
1文章数
0粉丝数
陈****关
1 文章 | 0 粉丝
原创

删除操作成功后,磁盘空间没释放?—磁盘幽灵

2025-08-22 06:17:04
1
0

第一章:MySQL假删除困局

深夜11点,运维工程师小明收到数据库服务器磁盘告警:空间使用率95%!分析发现BIG_TABLE表的2年前日志是元凶。他果断执行清理:

DELETE FROM BIG_TABLE WHERE create_time < '2023-01-01';  -- 删除12亿条历史日志   

确认事务提交后,监控显示表数据已消失。但次日清晨,服务器磁盘爆满,数据库陷入瘫痪——空间竟丝毫未释放!

分析:

InnoDB标记删除机制下,DELETE操作仅将数据标记为逻辑删除(打上删除标签),物理数据仍占据磁盘目的是支持MVCC(多版本并发控制),保证事务隔离性

空间归属权上,InnoDB不会主动将空间归还OS,仅允许新数据复用原有空间

释放方案

-- 彻底释放空间

OPTIMIZE TABLE BIG_TABLE;  -- 重建表消除碎片

第二章:Linux僵尸文件之谜

一周后,小明再遇磁盘告警!Apache日志文件access.log已增长至40GB。他火速执行:

bash

rm /var/log/apache/access.log  # 删除日志文件  

ls -l /var/log/apache/        # 确认文件消失  

然而两小时后,业务系统崩溃——磁盘空间依然耗尽!

分析:

inode引用计数器:

rm仅删除文件路径(目录项),inode引用数减1

Apache进程仍持有文件句柄,引用计数>0

空间持有者实锤:

lsof | grep deleted  # 关键命令揪出"僵尸文件"  

apache2 14836 root 1w REG 254,0 42G 65536 /var/log/apache/access.log (deleted)  

   如果一个进程在 rm 之前就已经打开了文件 A,那么它手里就握着一个指向该文件 inode 的文件描述符(File Descriptor)。 内核会为所有打开的文件维护一个引用计数器。只要还有进程持有文件描述符,即使目录中的链接已经被删除(link count = 0),内核也不会立即释放该文件的数据块,因为进程可能还要进行读写操作。此时,这个文件就变成了一个你看不到它,但它却真实存在的文件。这种设计是非常合理和安全的1保证进程稳定性:确保正在使用文件的程序不会突然因为文件被删除而崩溃或出错。2允许文件无缝替换:例如,日志文件可以被 rm 掉然后重新创建,而正在写入的进程可以毫不知情地继续向原来的文件描述符写入,新的数据会写到新创建的文件中

释放方案

# 方案1:优雅重启释放句柄 ,重启进程

kill -HUP 14836    # 通知Apache重建日志文件([网页12])  

# 方案2:清空文件立即释放空间,进程不能重启的情况下的选择 

echo "" > /proc/14836/fd/1  # 通过进程文件描述符清空  

最终启示录

删除 释放!

在计算机的世界里,可见的删除只是表象,空间的释放才是终极奥义。经验不足的同学,执行完删除操作可能就完事了,较有经验的同学会DOUBLE CHECK,确保删除真正生效。但经验丰富的同学,会用du命令检查空间的释放,提前发现问题。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0