GCE实例挂载Persistent Disk写入CSV出现lost+found问题排查
问题根因与修复方案
核心错误原因
- 代码逻辑存在缺陷:
myFile.getParentFile().mkdirs()会在磁盘未成功挂载到/mnt/point时,直接在系统盘生成/mnt/point本地目录,文件实际写入了系统盘的这个目录中。后续磁盘挂载到/mnt/point路径后,会遮挡原本地目录的内容,你看到的lost+found是Linux ext系列文件系统格式化后自带的默认目录,属于磁盘挂载后的正常显示内容,并非你的代码生成。 - SQL存储过程的执行用户没有挂载点
/mnt/point的写入权限,导致文件写入失败。 - 磁盘挂载未做持久化配置,实例重启后磁盘脱落,代码直接在系统盘创建目录写入文件,挂载后无法看到对应文件。
修复步骤
1. 校验磁盘挂载状态
执行df -h /mnt/point确认路径对应目标磁盘,而非本地目录。如果输出无对应磁盘信息,先完成磁盘挂载再运行代码。
2. 清理冗余本地目录
如果磁盘未挂载时已经生成了本地/mnt/point目录,执行以下命令清理并重新挂载:
umount /mnt/point 2>/dev/null rm -rf /mnt/point mkdir /mnt/point mount /dev/你的磁盘设备名 /mnt/point
同时将挂载配置写入/etc/fstab保证实例重启后自动挂载。
3. 配置挂载点权限
给SQL存储过程的执行用户授予读写权限,比如执行用户为mysql时:
chown mysql:mysql /mnt/point chmod 755 /mnt/point
4. 优化Java代码
删除自动创建父目录的逻辑,增加挂载状态校验,改用try-with-resources自动关流避免资源泄漏,修改后代码如下:
import java.io.File; import java.io.FileWriter; import java.io.IOException; public class file_write { public static void main(String[] args) throws IOException{ String filePath = "/mnt/point/file.csv"; File mountDir = new File("/mnt/point"); // 校验挂载点是否存在 if(!mountDir.exists() || !mountDir.isDirectory()) { throw new IOException("挂载点不存在"); } // 校验磁盘是否已挂载(ext系列文件系统挂载后会自带lost+found目录) if(!new File(mountDir, "lost+found").exists()) { throw new IOException("目标磁盘未挂载到指定路径"); } File myFile = new File(filePath); // FileWriter会自动创建文件,无需提前调用createNewFile try(FileWriter stringWriter = new FileWriter(myFile)) { for(int i = 0; i < 100000; i++) { stringWriter.write(i + ", "); stringWriter.write("something"); stringWriter.write(System.lineSeparator()); } } } }
内容的提问来源于stack exchange,提问作者Jason Li
相关产品推荐
相关产品推荐

