释放已删除日志占用的空间并保存录音

LinuxBeginner
立即练习

介绍

社区电台有一段待用于晚间节目的音频,但小型素材盘已满。维护者已经删除大型访问日志的名字,电台仍能提供归档,空间却没有回来。删除宝贵录音并不能解决真正的问题。

你将找到仍被 Nginx 持有的文件,使用其文档支持的日志重开信号,在原服务持续运行的情况下保存并播放完整新片段。只需基础终端经验,不需要 C、设备格式化或存储配置知识。本次排练的音频采用英语合成语音。

使用 Workstation 执行命令,在 Radio Player 收听。每个实验都有独立准备的故障现场。只操作 /home/labex/project/radio,只向已确认的电台主进程发信号;无关进程属于学习平台。

不停止电台即可回收空间

本步骤将把已满文件系统与一个具体的已删除文件关联起来,在保持电台运行时回收其磁盘块。

先听需要保留的内容

打开 Radio Player,播放 Archive recording,再播放 Incoming clip。归档已经位于素材盘,待保存片段在盘外等待。第三个播放器还没有完整的已保存录音。这些是合成排练语音,并非实时麦克风或真实采访。

在 Workstation 中,pwd 显示当前位置,ls 列出目录条目。终端从准备好的电台目录开始;必要时用 cd 返回:

cd /home/labex/project/radio
pwd
/home/labex/project/radio
ls

media/ 是隔离磁盘,incoming/ 位于实例的普通文件系统。services/ 保存本课程两个 Nginx 服务的配置和主进程 PID 文件。media.ext4 是 LabEx 准备的固定大小 backing file,请保持不变。你不会创建文件系统或修改挂载设置。

确认失败及边界

findmnt -T 显示某路径所在的文件系统。目标应恰好是 media 目录,来源为 /dev/loop... 设备,类型为 ext4。根文件系统的来源不同。loop 设备把本课程容量受限的磁盘映像呈现为块设备。

findmnt -T media -o TARGET,SOURCE,FSTYPE
findmnt -T incoming -o TARGET,SOURCE,FSTYPE

cp 复制文件。下面的复制特意预期会报 No space left on device,可能留下不完整的目标文件。不要用 sudo 执行;操作这些文件不需要它。

cp incoming/evening-recording.wav media/recordings/evening-recording.wav

这是真正在小型素材文件系统上发生的容量不足,原归档保持完好。df -h 用易读单位显示文件系统块容量。du -xsh 汇总从目录名字可达的文件分配块:-x 限定同一文件系统,-s 显示合计,-h 使用易读单位。

df -h media
du -xsh media

df 显示容量几乎耗尽,而 du 只看到较少占用。两者衡量的对象不同,仅凭差异不能认定原因:文件系统元数据、预留块、权限、不同挂载视图等也可能产生影响。

找到真实持有者

目录条目把名字映射到 inode,即文件系统保存的文件记录。硬链接计数表示有多少名字指向该 inode。进程还可以持有打开的文件描述符,也就是指向打开文件的编号引用。删除最后一个名字会让链接数降为零,但只有最后一个打开引用关闭后,文件块才会回收。

lsof 列出打开的文件。因为 Nginx 有 root 主进程,这次只读检查使用 sudo。-nP 避免查询主机名和端口名,+L1 选择链接数小于一的文件,+f -- media 选择 media 所在的文件系统,-a 取这些条件的交集。务必保留文件系统过滤;全局列表可能包含无关的已删除内存文件和平台进程。

sudo lsof -nP -a +L1 +f -- /home/labex/project/radio/media

预期出现两个指向 media/logs/access.log (deleted) 的 Nginx 行,分别是主进程和工作进程。阅读 PID、FD、DEVICE、SIZE/OFF、NLINK 和 NODE。两行设备和 inode 相同,NLINK 都为零;大小描述的是同一个文件,不能相加。4w 这样的 FD 表示编号 4 的描述符,以写方式打开。即使原名已消失,设备/inode 仍能识别此文件系统中的文件。

cat 显示文本。阅读电台真实配置和主进程 PID 文件。pid、access_log 的路径必须对应此电台和被删除的素材盘日志:

cat services/studio/nginx.conf
cat services/studio/nginx.pid

下面的 MASTER 是 shell 变量。$(...) 捕获命令输出,双引号使变量值作为一个参数传入。ps 显示所选进程,-o 选择列,-p 选择该 PID,--ppid 还会选择它的子进程。确认它就是过滤后的 lsof 行中的主进程,且配置路径属于本课程。另一行是工作进程,其父 PID 应为此主进程。

MASTER=$(cat services/studio/nginx.pid)
ps -ww -o pid,ppid,user,args -p "$MASTER" --ppid "$MASTER"

挂载点、路径或主进程身份不一致时不要行动。重新检查目录和配置,不要猜 PID,也不要给所有 Nginx 进程发送信号。

请此程序重新打开日志

信号的含义取决于程序。Nginx 将 USR1 定义为重新打开日志文件:关闭旧日志引用,再打开配置指定的名字。TERM 会停止程序,HUP 则有不同的重新加载语义。用 man nginx 阅读已安装手册,找到 SIGNALS,然后按 q 返回。Nginx 控制文档 也说明同一约定。

man nginx

kill 可以发送指定名称的信号,并不总意味着终止。向此 root 主进程发送信号需要 sudo。只将文档支持的信号发送给刚刚确认的主进程:

sudo kill -USR1 "$MASTER"

现在再次观察容量、持有者及主进程。重开是异步操作;若持有者暂时还出现在列表中,稍等片刻后重复这些只读观察。

df -h media
sudo lsof -nP -a +L1 +f -- /home/labex/project/radio/media
ps -ww -o pid,ppid,user,args -p "$MASTER" --ppid "$MASTER"

空间应已回收,已删除的素材盘日志行应消失,而主进程 PID 保持相同。此时过滤后的 lsof 结果为空是预期现象。你既没有停止电台,也没有释放其他文件系统中的文件。

curl -fsS 读取 URL,遇 HTTP 错误会失败,必要时显示简洁错误。这个正常电台请求必须仍可使用。随后用 tail -n 2 查看新命名的访问日志末尾两行:

curl -fsS http://127.0.0.1:8080/on-air.txt
tail -n 2 media/logs/access.log

预期看到 Community Radio: archive and live programme remain available. 以及新的 GET /on-air.txt 日志条目。原进程现在正在写入新命名日志。若空间没有回来,再次检查过滤后的持有者;不要删除归档、截断描述符、停止服务或重新创建挂载点。如果新日志不存在,检查未改动的配置,并针对正确主进程重复文档支持的重开。

保存并使用完整录音

本步骤将用完整待保存片段替换失败的部分副本,校验字节,并通过运行中的电台使用它。

待保存来源和归档各有不同作用,两个都要保留。向同一目标重新运行 cp 会替换失败尝试留下的部分文件,不会修改来源。

cp incoming/evening-recording.wav media/recordings/evening-recording.wav

cmp 比较每一个字节,文件相同时没有输出。复制后立即检查:

cmp incoming/evening-recording.wav media/recordings/evening-recording.wav

sha256sum 显示内容指纹。相同哈希提供另一种直观比较;评分还会将原归档及来源与准备时的字节对照。

sha256sum incoming/evening-recording.wav media/recordings/evening-recording.wav

两行的哈希必须相同。即使名字或大小看似正确,填零文件或稀疏文件也不是录音。复制到错误文件系统同样没有完成电台素材交付。

findmnt -T media/recordings/evening-recording.wav -o TARGET,SOURCE,FSTYPE

它必须仍属于原来隔离的 ext4 素材挂载点。检查电台能否提供真正保存的文件。-o 让 curl 把下载响应存到素材盘外,再将该响应与待保存片段比较:

curl -fsS http://127.0.0.1:8080/recordings/evening-recording.wav -o /tmp/radio-delivered.wav
cmp incoming/evening-recording.wav /tmp/radio-delivered.wav

返回 Radio Player 并重新加载。播放 Your saved recording,跳到接近结尾处,听完结束语。再次播放 Archive recording,用 Download saved recording 下载已保存录音。打开 Read the on-air message,应仍显示电台消息。浏览器音频需要用户主动播放,仅保存字节不会启动播放。

若已保存录音播放器报告格式或网络错误,再次比较来源与目标并检查 URL。满盘尝试可能留下被截断的 WAV 头部或数据,恢复后应重新复制未修改来源。若比较失败,不要修补音频头部,也不要修改来源去迁就损坏的目标。

df -h media

现在文件系统应有充足空闲容量和完整已保存片段。课程检查只读取最终文件、挂载身份、打开的描述符和真实服务状态,不会发送信号、复制音频、修复文件或替你创建录音。

总结

你通过区分名字、inode 和打开的描述符回收了真实磁盘空间。按文件系统过滤的调查将已删除日志对应到正确的 Nginx 主进程;它文档支持的 USR1 信号释放了旧引用,而没有替换进程。随后你保存、比对、下载并播放了完整片段,同时保留归档和电台服务。

df/du 的差异是线索,不是诊断。重开行为取决于程序,发送信号前应阅读其文档。本练习使用隔离 ext4 磁盘和合成语音,不教授格式化设备、任意终止进程或完整日志轮转策略。