Файлы, не закрывающиеся на BTRFS, и старые версии снова появляются

После большого количества тестирования и поиска справочных страниц по BTRFS мне нужна помощь некоторых пользователей Linux / BTRFS.

У меня есть Java-приложение, которое записывает файлы данных на диск с помощью утилиты java MappedByteBuffer. Это приложение использует буфер байтов ~16000 байтов при записи на диск. Когда новый файл записывается в него, создается временный файл с размером буфера, и из-за реализации java-файлов с расширением mem код не закрывает файл явно. Вместо этого мы вызываем Linux drop_caches, чтобы принудительно сбросить неиспользуемые карты памяти на диск.

  • На EXT4 эти файлы автоматически закрываются и размер файла корректно корректируется.
  • В BTRFS эти файлы остаются размером ~16000 байт и в них отсутствуют некоторые данные (возможно, проблемы с подкачкой)
  • На BTRFS, когда я удаляю эти файлы, и программное обеспечение перезапускается и снова создает файлы, одна и та же проблема возникает каждый раз, И даты изменения относятся к моменту, когда файлы были изначально созданы.

Информация о сервере: мы работаем с последней версией Centos 7.2 и обновляем патчи

  • ОС Centos 7 x64 (ядро 3.10.0-514.10.2.el7.x86_64)
  • btrfs-progs v4.4.1
  • Java 1.8.0_111

Тестирование выполнено

  • У нас есть сервер реплики, работающий на Ext4, и эта проблема не возникает

  • В настоящее время мы используем COW и сжатие, поэтому я попытался отключить их, перезагрузить, удалить старые данные и перезапустить программное обеспечение. Проблема все еще возникла

  • Я также попытался отключить space_cache, recovery, и я также попытался установить commit=5 с помощью flushoncommit... это также не помогло не закрывающимся файлам / неправильным датам изменения

1 ответ

и из-за реализации Java-файлов, отображаемых в формате Java, код явно не закрывает файл.

Это не имеет особого смысла. Отображения памяти с файловой поддержкой не требуют, чтобы их файловые дескрипторы оставались открытыми. Таким образом, вы абсолютно можете закрыть файл после создания сопоставленного буфера.

Вместо этого мы вызываем Linux drop_caches, чтобы принудительно сбросить неиспользуемые карты памяти на диск.

Это огромное излишество.

  1. используйте MappedByteBuffer::force для синхронизации изменений на диске
  2. переименовать временный файл
  3. fsync каталог, необходимый после переименования для обеспечения устойчивости к сбоям (см. ссылки ниже).


try(FileChannel dir = FileChannel.open(Paths.get("/path/directory"), StandardOpenOptions.READ)) {
  dir.force(true);
}

Другие вопросы по тегам