Hi, this is actually a Ticket, the good new is that is already pre-analyzed
and probably also the cause has been found.
I hope this is the right place to put this
TITLE: Wrong ERROR_DISK_FULL writing a blob on Windows
DESCRIPTION:
Having a sqlite database about 4.1 GB
writing blobs in some table, for instance using a statement like
INSERT INTO inodeCargo VALUES (1000, readfile ("ScreenShot.png"));
an error ERROR_DISK_FULL can be through wrongly (under certain
conditions)
Windows 7 64-bit
REPRODUCIBLE:
When the conditions are met, always reproducible
CAUSE :
windows function WriteFile return error 112 (ERROR_DISK_FULL) when
trying to write
1024 bytes using a offset = 4294966272 = 0xFFFFFC00 = FFFFFFFF - 2023
This was observed using the default mode (OVERLAPPED) although a
test compiling
the code with
#define SQLITE_WIN32_NO_OVERLAPPED
at the begining also failed.
PATCH:
The patch (see sqlite3_modified.c) work in my case, but obviously cannot
fix the mode NO_OVERLAPPED (it does not compile in this mode). Also
all procedures
using the buggy function (if this result to be the cause) should be
reviewed.
A more precise fix has to be developed by some expert in sqlite code.
ANALYSIS:
A sqlite db used to store files came in the conditions described
size of database file : 4.194.303 KB
size of journal file : 8 KB
size of the image (png file) : 4.417 KB
SQL Query returning systematically ERROR_DISK_FULL:
INSERT INTO inodeCargo VALUES (-24, 4522876, 0, readfile
("ScreenShot320.png"));
(hard disk of the test with about 1 TB free space)
Since the case was 100% reproducible I could debug the problem using
sqlite-amalgamation-3080803.zip (ver 3.8.8.3)
I tried sqlite-amalgamation-201503091040.zip as well with the same
result, so the problem was also not fixed in this pre-release.
In debug session I found that the error came from
static int winWrite (...
and it is given in the line
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
which is a call to a windows api function WriteFile
adding the extra debug messages into a file (see sqlite3_modified.c
function "static int winWrite")
this was the output before the fail (ERROR_DISK_FULL)
...
WRITE file=00000030, buffer=00EDBE08, amount=1024, offset=4294965248, lock=4
OVERLAPPED offset=4294965248, OffsetHigh=0
WRITE file=00000030, buffer=00EDC2E0, amount=1024, offset=4294966272, lock=4
OVERLAPPED offset=4294966272, OffsetHigh=0
Now note that
4294966272 = 0xFFFFFC00
and FFFFFFFF - FFFFFC00 = 3FF = 1023 !!!!! and we want to write
1024 bytes!!!
That this is a Microsoft bug is only a guess for what I have seen
debugging the code,
anyway if not I hope this analysis helps to find it the final cause of
the problem and it could be fixed.
Regards
Alejandro
-------------- next part --------------
TITLE: Wrong ERROR_DISK_FULL writing a blob on Windows
DATE: 2015.03.15
AUTHOR: Alejandro Xalabarder
DESCRIPTION:
Having a sqlite database about 4.1 GB
writing blobs in some table, for instance using a statement like
INSERT INTO inodeCargo VALUES (1000, readfile ("ScreenShot.png"));
an error ERROR_DISK_FULL can be through wrongly (under certain conditions)
Windows 7 64-bit
REPRODUCIBLE:
When the conditions are met, always reproducible
CAUSE :
windows function WriteFile return error 112 (ERROR_DISK_FULL) when trying to
write
1024 bytes using a offset = 4294966272 = 0xFFFFFC00 = FFFFFFFF - 2023
This was observed using the default mode (OVERLAPPED) although a test
compiling
the code with
#define SQLITE_WIN32_NO_OVERLAPPED
at the begining also fails.
PATCH:
The patch (see sqlite3_modified.c) has worked in my case, but obviously
cannot
fix the mode NO_OVERLAPPED since is not compiled in this mode. Also all
procedures
using the buggy function, if this result to be the cause, should be reviewed.
Therefore a more precise fix has to be developed by some expert in sqlite
code.
ANALYSIS:
A sqlite db used to store files came in the conditions described
size of database file : 4.194.303 KB
size of journal file : 8 KB
size of the image (png file) : 4.417 KB
SQL Query returning systematically ERROR_DISK_FULL:
INSERT INTO inodeCargo VALUES (-24, 4522876, 0, readfile
("ScreenShot320.png"));
(hard disk of the test with about 1 TB free space)
Since the case was 100% reproducible I could debug the problem using
sqlite-amalgamation-3080803.zip (ver 3.8.8.3)
I tried sqlite-amalgamation-201503091040.zip as well with the same
result, so the problem was also not fixed in this pre-release.
In debug session I found that the error came from
static int winWrite (...
and it is given in the line
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
which is a call to a windows api function WriteFile
adding the extra debug messages into a file (see sqlite3_modified.c function
"static int winWrite")
this was the output before the fail (ERROR_DISK_FULL)
...
WRITE file=00000030, buffer=00EDBE08, amount=1024, offset=4294965248, lock=4
OVERLAPPED offset=4294965248, OffsetHigh=0
WRITE file=00000030, buffer=00EDC2E0, amount=1024, offset=4294966272, lock=4
OVERLAPPED offset=4294966272, OffsetHigh=0
Now note that
4294966272 = 0xFFFFFC00
and FFFFFFFF - FFFFFC00 = 3FF = 1023 !!!!! and we want to write 1024
bytes!!!