Невозможно сохранить файл на диск "На устройстве не осталось места" - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть Java-программа, которая записывает файлы в каталог на виртуальной машине Linux. После записи 4,9 миллиона файлов происходит сбой со следующей ошибкой:

java.io.FileNotFoundException: /home/user/test/6BA30639CA0A2772AA0217312B3E847E2399E9A25F50F9960D6A670F4F2533EF.blob.lock (No space left on device)
        at java.io.RandomAccessFile.open0(Native Method)
        at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
        at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243)
        at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124)
        at com.xyz.azure.AsyncADLSHashFileUploader.SaveToLocalStore(AsyncADLSHashFileUploader.java:231)

Моя логика:

public String SaveToLocalStore(byte[] bytes, String subfolder) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(bytes);
        byte[] sha256 = md.digest();
        String sha256str = bytesToHex(sha256);

        Path tmpDir = Paths.get(LocalRootDirectory.toString(), subfolder);
        Path tmpFile = Paths.get(tmpDir.toString(), sha256str + ".tmp");
        Path localFile = Paths.get(LocalRootDirectory.toString(), subfolder, sha256str + ".blob");
        String dstFile = getDestFileFromSrcFile(localFile.toString());

        //noinspection ResultOfMethodCallIgnored
        tmpDir.toFile().mkdirs();

        //We can make a safe assumption that if the .blob file is present, that means that it has been fully written to
        if (!Files.exists(localFile)) {

        try (
                    RandomAccessFile randomAccessFile = new RandomAccessFile(localFile + ".lock", "rw");
                    FileChannel fc = randomAccessFile.getChannel();
                    FileLock fileLock = fc.tryLock()) {
                //if other thread/process is already handling this file... no point of us doing anything
                if (fileLock != null) {
                    //local file is already there, no need to write it again
                    try (FileOutputStream fos = new FileOutputStream(tmpFile.toString())) {
                        fos.write(bytes);
                        fos.flush();
                        fos.close();
                        Files.move(tmpFile, localFile, REPLACE_EXISTING);

                        if(statisticsEnabled) {
                            synchronized (StatsLock) {
                                StatsSavedHashes.add(localFile.toString());
                            }
                        }

                    } catch (Exception e) {
                        LOGGER.error("Failed to create local temp file: " + tmpFile + ": " + e, e);
                        //cleanup temp if it exists
                        Files.deleteIfExists(tmpFile);
                        throw e;
                    }
                }
            } catch (OverlappingFileLockException e) {
                //other thread is handling it already, so just carry one as if(fileLock == null) was at play
                return dstFile;
            }
            catch (Exception e) {
                LOGGER.error("Error while saving local file: " + localFile + ": " + e, e);
                throw e;
            }
        }
          return dstFile;
}

Я вижу, что доступно более 80% дискового пространства. Я также проверил наличие доступных inode в файловой системе.

Не знаю, в чем может быть проблема

Может кто-нибудь помочь мне с этим?

...