-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Copying files to a dataset and then verifying shows mismatches #227
Comments
The hole in the file seems to start and end at a 4 KiB aligned offset and is 32 KiB in size. The data after the hole is identical again. I'm letting it continue scanning to see if there are further differences. |
The harddrives have
and the cache SSDs have
|
The corruption also remains when I reread the data. |
I checked another file and the corruption start and end are again 4 KiB aligned but this time it is larger, 49152 bytes (48 KiB) |
Thanks for looking into this, I'll make it higher priority since we definitely don't want any corruption. If it's sections of nulls, i wonder if it is a seek/hole issue. I will dig deeper. Is there a relatively easily to make it happen, like close to a one-liner? |
I haven't found an easy way to reproduce yet, but it does keep happening when I transfer a big amount of data. I'm currently trying to see if any rclone options help, like I also checked for any errors in logs, but could not find anything, SMART values look good. Both systems I copy to/from have ECC memory, the source system is a Linux system running ZFS. Previous attempts to copy the same data to either NTFS / ReFS worked without issue. I'll also try to get some test running locally that writes random data from a fixed seed and compares the result. |
I also tried copying data with Windows Explorer and haven't had any corruption yet. Windows Explorer copies files sequentially in a single thread, rclone copies multiple files simultaneously and can even use multiple streams for single files. |
@EchterAgo commented 2 hours ago:
It would be nice to check if it can be reproduced by Linux or FreeBSD implementations of OpenZFS. At least Linux one contains some hard to reproduce bugs too. Eg: openzfs#12014 |
I'm using the Linux ZFS port for a long time already and I've never encountered corruption like this. The pool options are almost the same, except for case sensitive, RAIDZ2 instead of RAIDZ1 and only one cache device. I also use rclone a lot to copy to the Linux pool and I do sanity check the data, no problems so far. Yesterday I used Windows Explorer to copy the full 5TB to the Windows pool and it seems everything copied correctly. I also tried rclone with disabled preallocation and disabled sparse files and the corruption remained. I'm not sure I specified the options correctly for the remote though, so I'll retry this now. |
I've given up on #223 for now, after 5 weeks, I need a break from it. Sounds like I should try out |
Thanks @lundman. Wow, you're cool digger! Take rest and take care. :) And thanks for referencing the FileSpy tool, which I haven't heard before. It's a bit sad it isn't an open source thing, but it's impressive anyway! Cool. :) |
I have also done more testing, none of I plan to try some different filesystem options next. I'll also look into adding code to log zero data in some places. |
When Like 0..32KB 32KB..64KB 64KB..96KB. ..... etc? Or does it seek around a bit? I wonder if the "offset counter update" is wrong, or if it sends the offset each time |
With the options I used it should just write sequentially with a single thread, but I'll verify this using FileSpy. |
FileSpy_20230614_rclone_write.zip This is a capture of rclone writing the biggest file I have in the dataset. It does look sequential in 32KB chunks. There seems to be a FASTIO_WRITE call that fails in there. I'll also get a capture of Windows Explorer writing the same file. I also wonder if it is feasible to just capture the whole copy, then I could write a small tool to locate the problematic offsets in the capture. |
Ignore the FASTIO errors, it tries it first to see if we support it, and if not, does a regular IRP call.
Hmm what does I am aware of these two:
|
Ah ok this is just a snippet of a very large file? Then maybe it is up to 0x000000037B3C7000. So as long as it started at 0, then 1, 2, and now 3 that is fine. All writes should then end with 0x7000 and 0xf000 as long as the writes are 0x8000. They certainly do in the snippet I have. |
Yes, the file is 150GB, that is a normal file offset. I checked with smaller files and the high part of the address is zero. At the rate the FileSpy memory usage is growing when capturing I doubt I have enough memory to capture a whole rclone transfer. Is there any way to get FileSpy to log directly to disk? |
Initially I believed this to only affect larger files, but I've since seen this corruption in 1GB sized files as well. |
I can just copy the biggest file over and over again and capture its events. |
So the
So let me fix those before we test again |
Unlikely to affect things, you would have seen not-implemented in FileSpy. |
I tested with the latest changes and still see corruption. I also tested different sources for the copy, including local NTFS drives, with the same result. So far, anytime I copy enough data using I haven't found any |
Ok, I have a simple tool to reproduce: import uuid
import random
import math
import os
from pathlib import Path
ROOTPATH = Path('D:\\testdir')
DATA_BLOCK_SIZE = 32 * 1024
DATA_NUM_BLOCKS = math.floor((1 * 1024 * 1024 * 1024) / DATA_BLOCK_SIZE)
#DATA_NUM_BLOCKS = 3
def gen_file():
filename = ROOTPATH / str(uuid.uuid4())
start_state = random.getstate()
with open(filename, 'wb') as f:
for bi in range(0, DATA_NUM_BLOCKS):
data_block = random.randbytes(DATA_BLOCK_SIZE)
f.write(data_block)
random.setstate(start_state)
with open(filename, 'rb') as f:
for bi in range(0, DATA_NUM_BLOCKS):
disk_data_block = f.read(DATA_BLOCK_SIZE)
expected_data_block = random.randbytes(DATA_BLOCK_SIZE)
if disk_data_block != expected_data_block:
print(f'found mismatch in {filename} @ {bi * DATA_BLOCK_SIZE}')
def main():
random.seed()
os.makedirs(ROOTPATH, exist_ok=True)
while True:
gen_file()
if __name__ == "__main__":
main() it still needs a while to hit the errror. For my first try it wrote 888GB to hit the error. Same issue as with rclone but now isolated to only writing to ZFS. |
You can set a breakpoint on the mismatch print to stop the program when something goes wrong. I'll try to get a trace at that point tomorrow. |
I also tested with ZFS default options, same behavior. I'll check without cache devices, different redundancy options and just single device tomorrow. |
I also analyzed the file, it is the same zero filled 4k aligned corruption. I'll try this on a clean Windows install in a VM next. |
On another try I hit corruption after 200GB. |
Good news it will compress really well! Oh and there is no Registry |
I don't think there ever was a |
I still wonder why I didn't see the issue when trying without the L2ARC cache devices. Maybe it was just luck? I'll try this again. |
Ah yep, I never did add the MODULE_PARAM lines around it. |
Hah yeah, literally the first |
First copy passed, I am going to keep testing a few more times. |
By now I am convinced that this is fixed, so I am going to close this. If I hit it again I will reopen. |
That is exciting - I will massage it to fit with ZFS style a bit more, then move into main branches. |
The read function is just as complicated with special cases - even though we dont know of any issues, it may be worth copying as well. |
It seems that I set up remote access correctly so I will be able to run some tests while away from home. What I noticed yesterday is that my system seems to mostly hang but not crash after running the copy, deleting all the files and restarting the copy. Immediately before this almost all of the machines memory is used. After restarting importing the pool crashes in unlinked drain. I think I can trigger this quite reliably. |
Lets have a separate issue for unlinked drain bug - it should be easy (easier) to fix at least, just needs stack. Someone else mentioned we aren't freeing space on delete again - unsure how that happened since we've not touched that area. |
This occurred again today. It does seem to occur less frequently. This is on a completely different computer. |
What happened? "Copying files to a dataset and then verifying shows mismatches" ? |
Copied with |
boo, i dont like this news :) I assume we arent using the new clone-file feature, upstream is disabling it at the moment for making zero holes in files. |
I think this is still the same issue as previously, it just occurs less frequently. I set up a
I'll run that for a bit and see if that produces anything. |
openzfs#15526 sounds very similar to this. |
They certainly are panicking at the moment, I don't think we do any clonefile? Although, it does sound it happens outside of clonefile as well, so it is possible. Got anything for me to work on? I am adding the new CaseSensitive flag, but almost done. |
Yea, it does seem to happen even without clonefile. I don't have any issues right now other than the data corruption one, I'm still trying to get a API trace capture and cbuf from right after it happens, but it is difficult. |
It seems that after your |
The upstream issue also seems very timing sensitive. Maybe I should also try some different pool options. |
I'll revert to before the |
Sadly applying 76df45c did not change anything, so this is a different issue. |
@EchterAgo You and I worked hard on the issue of corruption, and I believe we fixed them all. #318 Can you let me know if this isn't the case? |
I'm using
rclone sync
to copy ~5TB of data to a ZFS dataset created with these options:After the copy is done, I use
rclone sync -c
to fully verify the contents of the copied files and it always comes up with differences. So far I've only seen it with bigger files, mostly with a 150GB disk image file, but also with some ~30GB image files.I used HxD to compare the files and it turns out there are sections filled with zeroes instead of the original data.
I'll try to diagnose this further.
The text was updated successfully, but these errors were encountered: