RocksDB loads a new `librocksdbjni*.so` file into the `/tmp` directory each time, causing a "No space left on device" error.
Opened this issue · 4 comments
Hi, @adamretter
I’m running a RaftJava project that uses RocksDB as its underlying storage. After running the project more than 1000 times, I encountered an error from RocksDB:
Caused by: java.lang.RuntimeException: Unable to load the RocksDB shared library
java.io.IOException: No space left on device
at org.rocksdb.RocksDB.loadLibrary(RocksDB.java:67)
at org.rocksdb.RocksDB.<clinit>(RocksDB.java:35)
I then checked the /tmp directory, and part of its contents are shown in the attached image. I believe that RocksDB is loading a new librocksdbjni*.so file every time, which eventually leads to running out of space in the /tmp directory.
I think this is an issue with RocksDB, and a potential fix would be to check whether a librocksdbjni*.so file already exists in the /tmp directory before attempting to load it, and if it does, skip the loading process.
Steps to reproduce the behavior
The version of RocksDB I’m using is as follows:
<dependency>
<groupId>org.rocksdb</groupId>
<artifactId>rocksdbjni</artifactId>
<version>5.1.4</version>
</dependency>
I'm looking forward to your response. Thank you!
@liang636600 those files are created as temporary files, and as we call File#deleteOnExit()
it should be deleted when the JVM stops, see: https://github.com/facebook/rocksdb/blob/main/java/src/main/java/org/rocksdb/NativeLibraryLoader.java#L133
Hi, @adamretter. Thank you very much for your response and the valuable insights. However, I was wondering if there might be an opportunity for improvement of the createTemp
function(
The primary goal of this function is to create a temporary file to copy the library to. It might be beneficial to first check whether a related library file already exists in the /tmp/ directory. If such a file exists, reusing it could potentially avoid creating a new temporary file. This adjustment could help prevent issues like the one I encountered, where repeatedly creating new files caused the /tmp/ directory to run out of disk space.
Thank you for considering this suggestion, and I look forward to your thoughts!
The primary goal of this function is to create a temporary file to copy the library to. It might be beneficial to first check whether a related library file already exists in the /tmp/ directory. If such a file exists, reusing it could potentially avoid creating a new temporary file.
This could lead to a race condition. As the user could have more than one JVM running RocksJava - it is impossible to know whether an existing file is in-use or will be deleted when a different JVM exits.
This adjustment could help prevent issues like the one I encountered, where repeatedly creating new files caused the /tmp/ directory to run out of disk space.
I am wondering how you were able to end up in this situation considering that the JVM is meant to delete the file when it stops. Any ideas?
My project is a pseudo-distributed system, and every time I run it, I start 30 nodes, each of which uses RocksDB for storage. As a result, each run creates a librocksdbjni*.so file in the /tmp directory for each node, totaling 30 such files. The system is shut down by killing the processes using kill -9 with the process IDs. I believe the main issue is that the JVM does not exit properly, which causes the librocksdbjni*.so files in my /tmp directory to accumulate with each run. Thank you for your response, you’re very kind!