Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Invoke the SQLITE_FCNTL_SIZE_HINT opcode on the sqlite3_file_control() interface for database files before extending the size of the file. The VFS can use this hint to preallocate space. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | branch-3.6.1 |
Files: | files | file ages | folders |
SHA1: |
9a083711712d652613c93b3ad96d4f73 |
User & Date: | drh 2010-05-17 15:33:24.000 |
Context
2010-05-17
| ||
15:52 | An improvement to the SQLITE_FCNTL_SIZE_HINT change that invokes the hint less often and only when really needed. (check-in: a1d20ceb9c user: drh tags: branch-3.6.1) | |
15:33 | Invoke the SQLITE_FCNTL_SIZE_HINT opcode on the sqlite3_file_control() interface for database files before extending the size of the file. The VFS can use this hint to preallocate space. (check-in: 9a08371171 user: drh tags: branch-3.6.1) | |
2010-03-03
| ||
15:49 | Fix some extra instances of the problematic constant in util.c on the 3.6.1 branch. (check-in: 527c71d54e user: dan tags: branch-3.6.1) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 | ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((unixFile*)id)->locktype; return SQLITE_OK; } } return SQLITE_ERROR; } /* ** Return the sector size in bytes of the underlying block device for | > > > > > > | 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 | ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((unixFile*)id)->locktype; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { sqlite3_int64 szFile = *(sqlite3_int64*)pArg; unixFile *pFile = (unixFile*)id; ftruncate(pFile->h, szFile); return SQLITE_OK; } } return SQLITE_ERROR; } /* ** Return the sector size in bytes of the underlying block device for |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 | ** every one of those pages out to the database file and mark them all ** as clean. */ static int pager_write_pagelist(PgHdr *pList){ Pager *pPager; PgHdr *p; int rc; if( pList==0 ) return SQLITE_OK; pPager = pList->pPager; /* At this point there may be either a RESERVED or EXCLUSIVE lock on the ** database file. If there is already an EXCLUSIVE lock, the following ** calls to sqlite3OsLock() are no-ops. | > | 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 | ** every one of those pages out to the database file and mark them all ** as clean. */ static int pager_write_pagelist(PgHdr *pList){ Pager *pPager; PgHdr *p; int rc; sqlite3_int64 szFile; /* Final size of databsae file */ if( pList==0 ) return SQLITE_OK; pPager = pList->pPager; /* At this point there may be either a RESERVED or EXCLUSIVE lock on the ** database file. If there is already an EXCLUSIVE lock, the following ** calls to sqlite3OsLock() are no-ops. |
︙ | ︙ | |||
3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 | } pList = sort_pagelist(pList); for(p=pList; p; p=p->pDirty){ assert( p->dirty ); p->dirty = 0; } while( pList ){ /* If the file has not yet been opened, open it now. */ if( !pPager->fd->pMethods ){ assert(pPager->tempFile); rc = sqlite3PagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); if( rc ) return rc; } /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. */ if( pList->pgno<=pPager->dbSize ){ | > > > > > > > > > | 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 | } pList = sort_pagelist(pList); for(p=pList; p; p=p->pDirty){ assert( p->dirty ); p->dirty = 0; } szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; while( pList ){ /* If the file has not yet been opened, open it now. */ if( !pPager->fd->pMethods ){ assert(pPager->tempFile); rc = sqlite3PagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); if( rc ) return rc; } /* Before the first write, give the VFS a hint of what the final ** file size will be. */ if( szFile>0 ){ sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); szFile = 0; } /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. */ if( pList->pgno<=pPager->dbSize ){ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability ** is used during testing and only needs to be supported when SQLITE_TEST ** is defined. */ #define SQLITE_FCNTL_LOCKSTATE 1 /* ** CAPI3REF: Mutex Handle {H17110} <S20130> ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite3_mutex]. It only | > > > > > > > > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 | ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability ** is used during testing and only needs to be supported when SQLITE_TEST ** is defined. ** ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it ** is often close. The underlying VFS might choose to preallocate database ** file space based on this hint in order to help writes to the database ** file run faster. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_SIZE_HINT 2 /* ** CAPI3REF: Mutex Handle {H17110} <S20130> ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite3_mutex]. It only |
︙ | ︙ |
Changes to test/filefmt.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 | db close file delete -force test.db sqlite3 db test.db db eval "PRAGMA auto_vacuum=OFF" db eval "PRAGMA page_size=$pagesize" db eval {CREATE TABLE t1(x)} file size test.db | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | db close file delete -force test.db sqlite3 db test.db db eval "PRAGMA auto_vacuum=OFF" db eval "PRAGMA page_size=$pagesize" db eval {CREATE TABLE t1(x)} file size test.db } [expr {$pagesize*2<$sqlite_pending_byte ? $pagesize*2 : $pagesize*3}] do_test filefmt-1.5.$pagesize.2 { hexio_get_int [hexio_read test.db 16 2] } $pagesize } } # The page-size must be a power of 2 |
︙ | ︙ |
Changes to test/io.test.
︙ | ︙ | |||
397 398 399 400 401 402 403 | INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } # File has grown - showing there was a cache-spill - but there # have been no calls to fsync(): list [file size test.db] [nSync] | | | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } # File has grown - showing there was a cache-spill - but there # have been no calls to fsync(): list [file size test.db] [nSync] } {38912 0} do_test io-3.3 { # The COMMIT requires a single fsync() - to the database file. execsql { COMMIT } list [file size test.db] [nSync] } {39936 1} } |
︙ | ︙ |