{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2025-01-20 16:07:35","updateBy":"admin","updateTime":"2025-01-20 16:07:35","remark":null,"params":{"@type":"java.util.HashMap"},"id":100,"articleTitle":"Linux中删除了文件但磁盘空间未释放","articleUrl":"linux_file_delete","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220908/ee03af4419724d50a127c34d6a588554.png","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"在CentOS 7中，会遇到一个问题，就是删除了文件，但磁盘空间并未正常释放。当文件被占用时执行了删除命令删除该文件就会出现这种情况。","articleContent":"在CentOS 7中，会遇到一个问题，就是删除了文件，但磁盘空间并未正常释放。当文件被占用时执行了删除命令删除该文件就会出现这种情况。以下是逐步解决方案：\n\n### **步骤 1：确认被删除但未释放的文件**\n\n1. **使用 `lsof` 命令查找被删除但仍被占用的文件**：\n\n   ```bash\n   lsof | grep deleted\n   ```\n\n   输出示例：\n\n   ```bash\n   java      1234  user  1w   REG   8,3  1000000  123456 /path/to/file.log (deleted)\n   ```\n\n   - 列出的文件路径旁会标注 `(deleted)`。\n\n- **关键列**：第二列（PID）表示占用文件的进程ID，第七列（SIZE）显示文件大小。\n\n2. **筛选占用空间较大的文件**：\n\n   ```bash\n   lsof | grep deleted | awk '{print $7, $9}' | sort -n -r | head -n 10\n   ```\n\n   - 按文件大小降序排列，显示前10个最大的被删除文件。\n\n---\n\n### **步骤 2：释放被占用的空间**\n\n#### **方法一：终止占用进程（适用于非关键进程）**\n\n1. **安全终止进程**：\n\n   ```bash\n   kill -15 1234  # 替换为实际PID，发送SIGTERM信号（允许进程清理资源）\n   ```\n\n2. **强制终止（仅当进程无响应时）**：\n\n   ```bash\n   kill -9 1234   # 发送SIGKILL信号（立即终止，可能丢失数据）\n   ```\n\n#### **方法二：清空文件内容（适用于日志等持续写入的文件）**\n\n1. **通过进程句柄清空文件**：\n\n   ```bash\n   cd /proc/1234/fd # 1234为pid，在此目录使用ls命令可以看到被此进程占用的所有文件\n   truncate -s 0 /proc/1234/fd/1  # 替换为实际文件描述符（FD列）\n   或\n   echo \"\" > /proc/1234/fd/1\n   ```\n\n   - **原理**：将文件大小截断为0，释放已占用的空间。\n   - **验证**：再次运行 `lsof | grep deleted`，确认文件大小（SIZE）变为0。\n\n#### **方法三：重启服务（适用于服务类进程）**\n\n1. **重启占用文件的服务**：\n\n   ```bash\n   systemctl restart service-name  # 如 httpd、mysql等\n   ```\n\n---\n\n### **步骤 3：验证磁盘空间是否释放**\n\n1. **查看磁盘使用情况**：\n\n   ```bash\n   df -h  # 检查对应分区的可用空间是否增加\n   ```\n\n2. **确认文件句柄已关闭**：\n\n   ```bash\n   ls -l /proc/1234/fd | grep deleted  # 替换为实际PID，应无输出\n   ```\n\n---\n\n### **步骤 4：预防措施**\n\n1. **避免直接删除正在写入的文件**：\n\n   - **日志文件**：使用 `logrotate` 管理日志轮转。\n\n     ```bash\n     yum install logrotate\n     ```\n\n   - **临时文件**：通过应用程序逻辑正确关闭文件句柄后再删除。\n\n2. **监控工具**：\n\n   - **使用 `ncdu` 分析磁盘空间**：\n\n     ```bash\n     yum install ncdu\n     ncdu /  # 扫描根目录\n     ```\n\n   - **设置告警**：通过 `cron` 定期检查大文件：\n\n     ```bash\n     # 每天检查一次大于1GB的文件\n     0 0 * * * find / -type f -size +1G -exec ls -lh {} \\; > /var/log/large_files.log\n     ```\n\n---\n\n### **示例场景**\n\n**问题**：Apache日志文件 `/var/log/httpd/access.log` 被删除但未释放空间。\n\n1. **查找占用进程**：\n\n   ```bash\n   lsof | grep deleted | grep httpd\n   ```\n\n   输出：\n\n   ```bash\n   httpd     5678 root    1w   REG   8,3  2.5G  789012 /var/log/httpd/access.log (deleted)\n   ```\n\n2. **清空文件内容**：\n\n   ```bash\n   truncate -s 0 /proc/5678/fd/1\n   ```\n\n3. **重启Apache以释放句柄**：\n\n   ```bash\n   systemctl restart httpd\n   ```\n\n---\n\n### **总结**\n\n| 步骤     | 命令/操作                        | 作用                     |\n| -------- | -------------------------------- | ------------------------ |\n| 确认占用 | `lsof | grep deleted`            | 列出被删除但未释放的文件 |\n| 终止进程 | `kill -15 PID` 或 `kill -9 PID`  | 安全或强制终止进程       |\n| 清空文件 | `truncate -s 0 /proc/PID/fd/N`   | 释放已删除文件的空间     |\n| 重启服务 | `systemctl restart service-name` | 重新打开文件句柄         |\n| 预防措施 | 配置 `logrotate`                 | 避免文件被直接删除       |\n\n通过以上步骤，可有效清理CentOS 7中被删除但仍被占用的文件，并预防类似问题发生。","categoryId":1,"viewCount":282,"categoryName":"Linux","author":"球接子","authorAvatar":null,"tagIds":[10],"tagNames":["Linux基础"]}}