Open zirkelc opened 1 month ago
Hi @zirkelc, thank you for reporting this. In order to help us understand what is happening, can you provide us with some additional information:
server.jvm.additional=
Error on attempt to preallocate log file version
for other databases?From the logs, it seems we are failing to preallocate a transaction log for the database because we cannot fetch the fileDescriptor. There can be multiple reasons for this, most of then OS/File System/JVM related. Hopefully the answers to the previous questions would help us pinpoint where this is coming from.
Hi @neo-ionut
What version of JDK are you using?
openjdk 17.0.10 2024-01-16 OpenJDK Runtime Environment Temurin-17.0.10+7 (build 17.0.10+7) OpenJDK 64-Bit Server VM Temurin-17.0.10+7 (build 17.0.10+7, mixed mode, sharing)
Do you pass any custom arguments to the jvm when starting Neo4j?
No, I start it via Neo4j via Docker
Can you share your config file used? If you cannot, can you share the part of the config that starts with
server.jvm.additional=
neo4j.conf
server.jvm.additional=-XX:+ExitOnOutOfMemoryError
server.jvm.additional=--add-opens=java.base/java.nio=ALL-UNNAMED
server.jvm.additional=--add-opens=java.base/java.io=ALL-UNNAMED
server.jvm.additional=--add-opens=java.base/sun.nio.ch=ALL-UNNAMED
server.memory.heap.initial_size=3500m
server.memory.heap.max_size=3500m
server.memory.pagecache.size=1800m
db.tx_log.rotation.retention_policy=3 days 5G
Lastly, do you notice the warning Error on attempt to preallocate log file version for other databases? Yes, it happens for other databases but not consistently. Here are the logs for the last 7 days:
root@nebula-neo4j:/neo4j/data# docker exec --interactive --tty neo4j awk -v start="$(date --date='7 days ago' +'%Y-%m-%d %H:%M:%S')" -v end="$(date +'%Y-%m-%d %H:%M:%S')" '$0 >= start && $0 <= end' /logs/debug.log | grep -i 'Error on attempt to preallocate log file version' 2024-07-30 00:17:01.504+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [pullupdipqkfh4/9b319e20] Error on attempt to preallocate log file version: 18. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-07-30 08:27:14.934+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [veynoubmf6z/68073522] Error on attempt to preallocate log file version: 0. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-07-30 08:27:14.946+0000 WARN [o.n.k.i.t.l.f.c.CheckpointFileChannelNativeAccessor] [veynoubmf6z/68073522] Error on attempt to preallocate log file version: 0. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-07-31 00:13:19.396+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [treazyxvjjp/4ab16d5b] Error on attempt to preallocate log file version: 1. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-07-31 00:14:17.814+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [doaba/7d4fa424] Error on attempt to preallocate log file version: 4. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-07-31 00:14:35.694+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [rc4lh/5579951b] Error on attempt to preallocate log file version: 9. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-08-02 07:41:06.442+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [pullupdipbgrti/ac159bbf] Error on attempt to preallocate log file version: 0. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-08-02 07:41:06.455+0000 WARN [o.n.k.i.t.l.f.c.CheckpointFileChannelNativeAccessor] [pullupdipbgrti/ac159bbf] Error on attempt to preallocate log file version: 0. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-08-02 07:53:51.834+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [pullupdipbgrti/ac159bbf] Error on attempt to preallocate log file version: 1. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-08-02 07:57:40.729+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [pullupdipbgrti/ac159bbf] Error on attempt to preallocate log file version: 2. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-08-02 08:00:07.780+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [pullupdipbgrti/ac159bbf] Error on attempt to preallocate log file version: 3. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.' 2024-08-05 00:11:15.713+0000 WARN [o.n.k.i.t.l.f.LogFileChannelNativeAccessor] [treazyxvjjp/4ab16d5b] Error on attempt to preallocate log file version: 2. Error: ErrorCode=-1, errorMessage='Incorrect file descriptor.'
After reading this article from Neo4j, I added these three flags:
server.jvm.additional=--add-opens=java.base/java.nio=ALL-UNNAMED
server.jvm.additional=--add-opens=java.base/[java.io](http://java.io/)=ALL-UNNAMED
server.jvm.additional=--add-opens=java.base/[sun.nio.ch](http://sun.nio.ch/)=ALL-UNNAMED
However, it doesn't look like that it's helping regarding the warnings and errors.
When I looked through the /neo4j/data/transactions/*
files, I noticed that there are many older neostore.transaction.db.*
files For example for the database fashionbeauty19qnngn
there are files from
transactions/fashionbeauty19qnngn:
total 458892
drwxr-xr-x 2 7474 7474 4096 Jul 27 00:09 .
drwxr-xr-x 25 7474 7474 4096 Aug 5 09:51 ..
-rw-r--r-- 1 7474 7474 5928 Aug 5 06:56 checkpoint.0
-rw-r--r-- 1 7474 7474 268646770 Jul 23 16:23 neostore.transaction.db.13
-rw-r--r-- 1 7474 7474 201228573 Jul 28 00:16 neostore.transaction.db.14
If I'm not mistaken, shouldn't the transactions log files be deleted according to db.tx_log.rotation.retention_policy=3 days 5G
?
This is indeed quite strange. From the looks of it, we are having issue preallocateing the log files, but it seems that this is not for everything, only a few cases? My suspicion was that we can't use sun.nio
, but the config looks ok. Can you maybe check the beginning of the debug log to see if the settings actually get passed correctly? You should be able to find all the server.jvm.additional
.
Additionally, do you think it would be possible to try to enable some additional debug information? We have a flag that enables extra prints for reflection issues. All you need to do is add the following to the config and restart. And then check if exceptions are being printed in the log
server.jvm.additional=-Dorg.neo4j.io.pagecache.impl.SingleFilePageSwapper.printReflectionExceptions=true
I also am a bit unsure what is happening with the deletion. Indeed the policy should have deleted the older file. Can you confirm that a checkpoint triggered after the second file was created? (log files are pruned on checkpointing).
Last thing - I am not sure how you mount volumes in Docker, but maybe there is something around how Docker mounts disks or some permissions that affects this? (a bit of a shot in the dark)
I added server.jvm.additional=-Dorg.neo4j.io.pagecache.impl.SingleFilePageSwapper.printReflectionExceptions=true
to the neo4j.conf and restarted it.
The Vm arguments look okay from what I can tell:
VM Arguments: [-XX:+ExitOnOutOfMemoryError, --add-opens=java.base/java.nio=ALL-UNNAMED, --add-opens=java.base/java.io=ALL-UNNAMED, --add-opens=java.base/sun.nio.ch=ALL-UNNAMED, -Dorg.neo4j.io.pagecache.impl.SingleFilePageSwapper.printReflectionExceptions=true, -Dfile.encoding=UTF-8, -Xms3584000k, -Xmx3584000k]
Additionally, do you think it would be possible to try to enable some additional debug information? We have a flag that enables extra prints for reflection issues. All you need to do is add the following to the config and restart. And then check if exceptions are being printed in the log server.jvm.additional=-Dorg.neo4j.io.pagecache.impl.SingleFilePageSwapper.printReflectionExceptions=true
The debug.log doesn't contain any new errors or exception yet, but they usually come at night when we load data from 3rd party systems into Neo4j. I will follow up with new data tomorrow.
I also am a bit unsure what is happening with the deletion. Indeed the policy should have deleted the older file. Can you confirm that a checkpoint triggered after the second file was created? (log files are pruned on checkpointing).
I checked the transaction log when the database fashionbeauty19qnngn
was restarted:
[fashionbeauty19qnngn/0a214b04] --------------------------------------------------------------------------------
[fashionbeauty19qnngn/0a214b04] [ Transaction log ]
[fashionbeauty19qnngn/0a214b04] --------------------------------------------------------------------------------
[fashionbeauty19qnngn/0a214b04] Transaction log files stored on file store: device - `Volume `, type - `Unknown', max io - '1.250MiB'.
[fashionbeauty19qnngn/0a214b04] Transaction log metadata:
[fashionbeauty19qnngn/0a214b04] - current kernel version used in transactions: V5_15
[fashionbeauty19qnngn/0a214b04] - last committed transaction id: 37220
[fashionbeauty19qnngn/0a214b04] Transaction log files:
[fashionbeauty19qnngn/0a214b04] - existing transaction log versions: 13-14
[fashionbeauty19qnngn/0a214b04] - oldest transaction 32992 found in log with version 13
[fashionbeauty19qnngn/0a214b04] - files: (filename : creation date - size)
[fashionbeauty19qnngn/0a214b04] neostore.transaction.db.13: 2024-07-23 16:23:59.289+0000 - 256.2MiB
[fashionbeauty19qnngn/0a214b04] neostore.transaction.db.14: 2024-07-28 00:16:04.420+0000 - 191.9MiB
[fashionbeauty19qnngn/0a214b04] - total size of files: 448.1MiB
[fashionbeauty19qnngn/0a214b04] Checkpoint log files:
[fashionbeauty19qnngn/0a214b04] - existing checkpoint log versions: 0-0
[fashionbeauty19qnngn/0a214b04] - last checkpoint: CheckpointInfo[transactionLogPosition=LogPosition{logVersion=14, byteOffset=201228573}, storeId=StoreId{creationTime=1721741017484, random=-8796547720763615136, storageEngineName='record', formatName='ali>
[fashionbeauty19qnngn/0a214b04]
It shows the two transaction log files from the file system. Then I created a lot of dummy changes to force Neo4j to create a new log file neostore.transaction.db.15
. Shortly after the checkpoint was triggered to prune old log files, but nothing was removed:
2024-08-05 14:04:44.233+0000 INFO [o.n.k.d.Database] [fashionbeauty19qnngn/0a214b04] Rotated to transaction log [/data/transactions/fashionbeauty19qnngn/neostore.transaction.db.15] version=14, last transaction in previous log=37227, rotation took 48 millis.
2024-08-05 14:06:14.016+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] [fashionbeauty19qnngn/0a214b04] Checkpoint triggered by "Scheduled checkpoint for every 15 minutes threshold" @ txId: 37227 checkpoint started...
2024-08-05 14:06:15.825+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] [fashionbeauty19qnngn/0a214b04] Checkpoint triggered by "Scheduled checkpoint for every 15 minutes threshold" @ txId: 37227 checkpoint completed in 1s 808ms. Checkpoint flushed 2033 pages (0% of total available pages), in 2018 IOs. Checkpoint performed with IO limit: 600, paused in total 14 times( 1238 millis).
2024-08-05 14:06:15.850+0000 INFO [o.n.k.i.t.l.p.LogPruningImpl] [fashionbeauty19qnngn/0a214b04] No log version pruned. The strategy used was '3 days 5368709120 size'.
The file system still shows the old file neostore.transaction.db.13
:
/neo4j/data/transactions/fashionbeauty19qnngn: ls -al
total 792660
drwxr-xr-x 2 7474 7474 4096 Aug 5 14:04 .
drwxr-xr-x 25 7474 7474 4096 Aug 5 09:51 ..
-rw-r--r-- 1 7474 7474 6392 Aug 5 14:06 checkpoint.0
-rw-r--r-- 1 7474 7474 268646770 Jul 23 16:23 neostore.transaction.db.13
-rw-r--r-- 1 7474 7474 274574039 Aug 5 14:04 neostore.transaction.db.14
-rw-r--r-- 1 7474 7474 268435456 Aug 5 14:04 neostore.transaction.db.15
Could it be (assumption) that checkpoint.0
acts as kind of a state (like a pointer on a timeline) for Neo4j, which it updates every time it prunes the log files. If so, perhaps the older transaction log files were tried to be removed, but for some reason it failed. Then, Neo4j didn't handle this case properly and moved the checkpoint.0
forward in time. Now it's the case that checkpoint.0
is in the future compared to the old neostore.transaction.db.13
file, so it is not in scope by the transaction log file pruning algorithm?
Last thing - I am not sure how you mount volumes in Docker, but maybe there is something around how Docker mounts disks or some permissions that affects this? (a bit of a shot in the dark)
I will look into this!
In regards to the checkpointing and log pruning - in 5.10 we have changed what we use as reference for when a file should be deleted. After that version, we use the first timestamp from the following version as approximation of the timestamp of the last entry in the current log version. The reason for this was that sometimes we've seen situations where a log is created but there is no activity for a while. Because of this there were some edge cases where incremental backup would fail.
So it's not the creation timestamp of the file that you should check, but the first transaction in the next one :) I hope this makes a bit of sense.
It looks like there weren't any issues for Incorrect file descriptor
tonight. Maybe the three JVM args --add-opens=java.base/*
did solve it?
However, I noticed two other error yesterday:
2024-08-05 14:20:03.445+0000 ERROR [o.n.k.i.u.w.DefaultFileDeletionEventListener] '.checkpoint.0.swp' which belongs to the 'fashionbeauty19qnngn' database was deleted while it was running.
2024-08-05 16:58:48.764+0000 ERROR [o.n.k.i.u.w.DefaultFileDeletionEventListener] '.neostore.transaction.db.13.swp' which belongs to the 'fashionbeauty19qnngn' database was deleted while it was running.
Guessing from the timestamp, it looks like I opened these files with the editor and created a swap file which was deleted automatically afterwards.
So it's not the creation timestamp of the file that you should check, but the first transaction in the next one :) I hope this makes a bit of sense. Does this mean the oldest transactions file
neostore.transaction.db.13
from July 23 could contain transactions from the last 3 days (retention policy = 3 days 5G)? In which encoding or format are these files encoded? I opened it withnano
but it mostly shows gibberish.
It looks like there weren't any issues for Incorrect file descriptor tonight. Maybe the three JVM args --add-opens=java.base/* did solve it?
That is great to hear, I do think it did solve it.
However, I noticed two other error yesterday:
Yes, we are watching the folder and issuing warning if we see anything disappearing. I do think you might have created those files and, as such, those warning can be ignored.
Does this mean the oldest transactions file neostore.transaction.db.13 from July 23 could contain transactions from the last 3 days (retention policy = 3 days 5G)?
Not really. It means we use the FIRST timestamp from 14 as the "prune date" for 13. Why? Because it's faster to do that then use the last one from 13 instead. (as we would need to parse the whole file to get to that).
In which encoding or format are these files encoded?
These are binary files. We don't officially document their format (or support it), but the code is available part of our community edition, so it should be easy-ish to figure it out from there.
The logs are not showing any warnings or error for the last couple of days, so I guess the VM arguments were the missing piece. Maybe it would make sense to add the three arguments from this article to the official docs? The article mentions it affects Neo4j before v5.14, but I'm running v5.17 already.
I'm running Neo4j v5.17.0 via Docker on Ubuntu 22.04.4 LTS.
I'm using the CDC feature and found the following errors in the debug logs:
This error is preceded by lots of warnings like these:
I'm not sure if the warning are related to the CDC issue, but it looks like something broke the CDC service, maybe because the transactions logs could not be created.
Here is the full debug log filter for the database
fashionbeauty19qnngn
as gist, because it's too big for this issue: https://gist.github.com/zirkelc/8e74a6830e37d802778a2e41f22184d7