On 04/24/2013 04:44 PM, Sašo Kiselkov wrote:
> On 04/24/2013 04:41 PM, Richard Hipp wrote:
>> On Wed, Apr 24, 2013 at 10:28 AM, Sašo Kiselkov 
>> <skiselkov...@gmail.com>wrote:
>>
>>> On 04/24/2013 03:57 PM, Richard Hipp wrote:
>>>> On Wed, Apr 24, 2013 at 8:28 AM, Sašo Kiselkov <skiselkov...@gmail.com
>>>> wrote:
>>>>
>>>>> I'm running into I/O errors when trying to access a sqlite3 database
>>>>> which is using WAL from my app. While using journal_mode=delete,
>>>>> everything is fine, but as soon as I switch over to journal_mode=wal, I
>>>>> just get a load of I/O errors on any query, regardless if it is a SELECT
>>>>> or UPDATE/INSERT.
>>>>>
>>>>
>>>>
>>>> Can you please turn on error logging (as described at
>>>> http://www.sqlite.org/draft/errlog.html) and let us know more details
>>> about
>>>> the I/O error you are seeing?
>>>
>>> Here's my error log:
>>>
>>> #4874: os_unix.c:27116: (22) fallocate(/root/test/idx/block.db-shm) -
>>> Invalid argument
>>>
>>
>> So apparently, the call to fallocate() on the file
>> /root/test/idx/block.db-shm is failing with errno==22.  Do you have any
>> idea why that might be?
>>
>> Can you tell me exactly which version of SQLite you are using so that I can
>> figure out what line 27116 says?  Or maybe look at line 27116 of sqlite3.c
>> yourself and let us know which line of code the error is occurring on?
> 
> I'm running sqlite-autoconf-3071602, here's the relevant bits of code
> from sqlite3.c:
> 
> if( sStat.st_size<nByte ){
>   /* The requested memory region does not exist. If bExtend is set to
>    ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
>    **
>    ** Alternatively, if bExtend is true, use ftruncate() to allocate
>    ** the requested memory region.
>    */
>   if( !bExtend ) goto shmpage_out;
> #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
>   if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
>     rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
>                       pShmNode->zFilename);
>     goto shmpage_out;
>   }
> #else
>   if( robust_ftruncate(pShmNode->h, nByte) ){
>     rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
>                       pShmNode->zFilename);
>     goto shmpage_out;
>   }
> #endif
> }

I think I've found it. Dtracing around in the system, this is the ZFS
kernel code that's being called:

  6    -> zfs_space
  6      -> rrw_enter
  6        -> rrw_enter_read
  6        <- rrw_enter_read
  6      <- rrw_enter
  6      -> rrw_exit
  6      <- rrw_exit
  6    <- zfs_space

Looking at the implementation of zfs_space, I can see this tidbit:

/*
 * ...
 * Currently, this function only supports the `F_FREESP' command.
 * ...
 */
static int
zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag,
    offset_t offset, cred_t *cr, caller_context_t *ct)
{
        ...
        if (cmd != F_FREESP) {
                ZFS_EXIT(zfsvfs);
                return (SET_ERROR(EINVAL));
        }
        ...
}

So it appears that F_ALLOCSP isn't support on ZFS. This appears to be
the case for all platforms where ZFS is available, not just SunOS. For
instance, ZFS on Linux has this problem as well:
https://github.com/zfsonlinux/zfs/blob/master/module/zfs/zfs_vnops.c#L4225-L4228

Is there some way to work around posix_fallocate and still have WAL
support in SQLite?

Cheers,
--
Saso
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to