In btreeCreateTable, a new page is allocated by allocateBtreePage function
without any failures.
In normal case, this should be failed because of there is no space to write
journal file.
jrnlWrite function called from allocateBtree is passed by writing memory
block(no real file) in atomic write mode.

After finished of allocateBtreePage, ptrmapPut function called to update
the pointer-map and meta-data with the new root-page number.
Finally, this function is failed at sqlite3PagerWrite because of real file
write is called at this time.
But, the newly allocated page number in btree structure(or pager?) didn't
changed to original value.

In my opinion, issue point is updated page number is not returned to
previous value.
the allocateBtreePage function doesn't return disk full error and this
wrong value is remained until next query execution.
ptrmapPut function doesn't clear this page number.

If I turn off "atomic write" option, it works very well. (allocateBtreePage
function will return disk full error and page number will be replaced to
original value)

My question is how to replace page number in btree structure to original
value when failure is occurred after call of allocateBtreePage funciton.
Or... is there any better code for this?

Thank you.
Yongil Jang.



2012/11/26 Yongil Jang <yongilj...@gmail.com>

> Hi, there.
>
> I just found some illegal processing of SQLite.
> As I mentioned in title, "CREATE TABLE" query returns "database disk image
> is malformed" when disk is full and "SQLITE_IOCAP_ATOMIC" and
> "SQLITE_DEFAULT_AUTOVACUUM" is enabled.
> Here is my test scripts.
>
> sudo mkdir /mnt/db
> sudo chmod 777 /mnt/db
> sudo mount -t tmpfs -o size=16K tmpfs /mnt/db
> /home/yi.jang/git/sqlite_source/sqlite3 /mnt/db/test.db
>
> SQLite version 3.7.13 2012-06-11 02:05:22
> Enter ".help" for instructions
> Enter SQL statements terminated with a ";"
> sqlite> pragma journal_mode=persist;
> persist
> sqlite> pragma page_size=4096;
> sqlite> create table a (id);
> sqlite> create table b (id);
> *Error: database or disk is full*
> sqlite> create table b (id);
> *Error: database disk image is malformed*
> sqlite>
>
> What I attached options to Makefile are as following.
>
> -DSQLITE_ENABLE_ATOMIC_WRITE
> -DSQLITE_DEFAULT_AUTOVACUUM=1
> -DSQLITE_DEFAULT_PAGE_SIZE=4096
>
> sqlite3.c is also changed.
>
> static int unixDeviceCharacteristics(sqlite3_file *id){
>   unixFile *p = (unixFile*)id;
>   if( p->ctrlFlags & UNIXFILE_PSOW ){
>     return SQLITE_IOCAP_POWERSAFE_OVERWRITE | SQLITE_IOCAP_ATOMIC;
>   }else{
>     return SQLITE_IOCAP_ATOMIC;
>   }
> }
>
> B.R.
> Yongil Jang.
>
>
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to