mirror of https://github.com/sqlite/sqlite
Add experimental unix-only file-control to grow and truncate the database file by a configurable chunk size.
FossilOrigin-Name: 7cf0e851d4c5e826ea22ed08291b7c91d7b1abc7
This commit is contained in:
parent
d2de9f4e68
commit
6e09d69c92
32
manifest
32
manifest
|
@ -1,8 +1,5 @@
|
||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
C Add\sexperimental\sunix-only\sfile-control\sto\sgrow\sand\struncate\sthe\sdatabase\sfile\sby\sa\sconfigurable\schunk\ssize.
|
||||||
Hash: SHA1
|
D 2010-07-27T18:34:16
|
||||||
|
|
||||||
C Increase\sthe\sversion\snumber\sto\s3.7.1\sdue\sto\sthe\sAPI\senhancement\sof\sthe\sprevious\ncheck-in.
|
|
||||||
D 2010-07-26T16:40:04
|
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
|
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
|
@ -157,7 +154,7 @@ F src/os.c 60178f518c4d6c0dcb59f7292232281d7bea2dcf
|
||||||
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
|
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
|
||||||
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
||||||
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
||||||
F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248
|
F src/os_unix.c 77e963fbbed6a2ca9b7c9115ae06f05181729490
|
||||||
F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
|
F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
|
||||||
F src/pager.c 78ca1e1f3315c8227431c403c04d791dccf242fb
|
F src/pager.c 78ca1e1f3315c8227431c403c04d791dccf242fb
|
||||||
F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
|
F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
|
||||||
|
@ -173,14 +170,14 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
||||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||||
F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c
|
F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c
|
||||||
F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
|
F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
|
||||||
F src/sqlite.h.in e789728101d821fd4307208aa11e332e51eedbf9
|
F src/sqlite.h.in 3b201a7aced2227339c2bba8dfbee47a823d43ad
|
||||||
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
||||||
F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5
|
F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5
|
||||||
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
|
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
|
||||||
F src/status.c 51f65ba9768846c071fa621624d55d6866fce28b
|
F src/status.c 51f65ba9768846c071fa621624d55d6866fce28b
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
F src/tclsqlite.c ae1e4fb653c91ddad7e2534d209711a12604ccc4
|
F src/tclsqlite.c ae1e4fb653c91ddad7e2534d209711a12604ccc4
|
||||||
F src/test1.c ff3b4533fc4d78d1bff2ef831a5791db55096ed3
|
F src/test1.c 0bfcda72f9f8ab5c0e90fac05cc22c1c21131ddf
|
||||||
F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
|
F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
|
||||||
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
|
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
|
||||||
F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee
|
F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee
|
||||||
|
@ -354,6 +351,7 @@ F test/exclusive.test 5fe18e10a159342dd52ca14b1554e33f98734267
|
||||||
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
|
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
|
||||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||||
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
|
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
|
||||||
|
F test/fallocate.test 2aa524a237893aca5b2a7ad5d450ee4801b4abdd
|
||||||
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
||||||
F test/filefmt.test 5d271bf467e6557fe7499dcc8203069c9dc5825e
|
F test/filefmt.test 5d271bf467e6557fe7499dcc8203069c9dc5825e
|
||||||
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
|
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
|
||||||
|
@ -841,14 +839,10 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 008368b2bd1513e2df21c2070548c6fc94abebb1
|
P 1d7571e4be6d96aec13cd8b3b7b10b8dc44d19a5
|
||||||
R e0e547721eadb5865947ac95d9a5637b
|
R 06d24f984109c26ad9ccb04075848e30
|
||||||
U drh
|
T *branch * experimental
|
||||||
Z b2f076ca75f409c11b1173e904fc1e43
|
T *sym-experimental *
|
||||||
-----BEGIN PGP SIGNATURE-----
|
T -sym-trunk *
|
||||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
U dan
|
||||||
|
Z 84d3b6ef35de3d3ded4f7f20ba0de5c7
|
||||||
iD8DBQFMTbpnoxKgR168RlERAgRsAKCEDv9PrVdoUqb+GgrX9p308vOjrgCgi4/A
|
|
||||||
Wv1UV7AZmSjiGasHOtjRZXM=
|
|
||||||
=082N
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1d7571e4be6d96aec13cd8b3b7b10b8dc44d19a5
|
7cf0e851d4c5e826ea22ed08291b7c91d7b1abc7
|
|
@ -210,6 +210,7 @@ struct unixFile {
|
||||||
int fileFlags; /* Miscellanous flags */
|
int fileFlags; /* Miscellanous flags */
|
||||||
const char *zPath; /* Name of the file */
|
const char *zPath; /* Name of the file */
|
||||||
unixShm *pShm; /* Shared memory segment information */
|
unixShm *pShm; /* Shared memory segment information */
|
||||||
|
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
int openFlags; /* The flags specified at open() */
|
int openFlags; /* The flags specified at open() */
|
||||||
#endif
|
#endif
|
||||||
|
@ -2763,6 +2764,43 @@ static int unixWrite(
|
||||||
}
|
}
|
||||||
SimulateIOError(( wrote=(-1), amt=1 ));
|
SimulateIOError(( wrote=(-1), amt=1 ));
|
||||||
SimulateDiskfullError(( wrote=0, amt=1 ));
|
SimulateDiskfullError(( wrote=0, amt=1 ));
|
||||||
|
|
||||||
|
/* If the user has configured a chunk-size for this file, it could be
|
||||||
|
** that the file needs to be extended at this point.
|
||||||
|
*/
|
||||||
|
if( pFile->szChunk && amt==0 ){
|
||||||
|
i64 nSize; /* Required file size */
|
||||||
|
struct stat buf; /* Used to hold return values of fstat() */
|
||||||
|
int rc = fstat(pFile->h, &buf);
|
||||||
|
if( rc!=0 ) return SQLITE_IOERR_FSTAT;
|
||||||
|
nSize = ((offset+amt+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
|
||||||
|
if( nSize>(i64)buf.st_size ){
|
||||||
|
#ifdef HAVE_POSIX_FALLOCATE
|
||||||
|
if( posix_fallocate(pFile->h, buf.st_size, nSize-buf.st_size) ){
|
||||||
|
return SQLITE_IOERR_WRITE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* If the OS does not have posix_fallocate(), fake it. First use
|
||||||
|
** ftruncate() to set the file size, then write a single byte to
|
||||||
|
** the last byte in each block within the extended region.
|
||||||
|
*/
|
||||||
|
int nBlk = buf.st_blksize; /* File-system block size */
|
||||||
|
i64 iWrite; /* Next offset to write to */
|
||||||
|
|
||||||
|
if( ftruncate(pFile->h, nSize) ){
|
||||||
|
pFile->lastErrno = errno;
|
||||||
|
return SQLITE_IOERR_TRUNCATE;
|
||||||
|
}
|
||||||
|
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
|
||||||
|
do {
|
||||||
|
wrote = seekAndWrite(pFile, iWrite, "", 1);
|
||||||
|
iWrite += nBlk;
|
||||||
|
} while( wrote==1 && iWrite<nSize );
|
||||||
|
if( wrote!=1 ) amt = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( amt>0 ){
|
if( amt>0 ){
|
||||||
if( wrote<0 ){
|
if( wrote<0 ){
|
||||||
/* lastErrno set by seekAndWrite */
|
/* lastErrno set by seekAndWrite */
|
||||||
|
@ -2772,6 +2810,7 @@ static int unixWrite(
|
||||||
return SQLITE_FULL;
|
return SQLITE_FULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2973,12 +3012,23 @@ static int unixSync(sqlite3_file *id, int flags){
|
||||||
** Truncate an open file to a specified size
|
** Truncate an open file to a specified size
|
||||||
*/
|
*/
|
||||||
static int unixTruncate(sqlite3_file *id, i64 nByte){
|
static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||||
|
unixFile *pFile = (unixFile *)id;
|
||||||
int rc;
|
int rc;
|
||||||
assert( id );
|
assert( pFile );
|
||||||
SimulateIOError( return SQLITE_IOERR_TRUNCATE );
|
SimulateIOError( return SQLITE_IOERR_TRUNCATE );
|
||||||
rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
|
|
||||||
|
/* If the user has configured a chunk-size for this file, truncate the
|
||||||
|
** file so that it consists of an integer number of chunks (i.e. the
|
||||||
|
** actual file size after the operation may be larger than the requested
|
||||||
|
** size).
|
||||||
|
*/
|
||||||
|
if( pFile->szChunk ){
|
||||||
|
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ftruncate(pFile->h, (off_t)nByte);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
((unixFile*)id)->lastErrno = errno;
|
pFile->lastErrno = errno;
|
||||||
return SQLITE_IOERR_TRUNCATE;
|
return SQLITE_IOERR_TRUNCATE;
|
||||||
}else{
|
}else{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -2989,8 +3039,8 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
||||||
** when restoring a database using the backup API from a zero-length
|
** when restoring a database using the backup API from a zero-length
|
||||||
** source.
|
** source.
|
||||||
*/
|
*/
|
||||||
if( ((unixFile*)id)->inNormalWrite && nByte==0 ){
|
if( pFile->inNormalWrite && nByte==0 ){
|
||||||
((unixFile*)id)->transCntrChng = 1;
|
pFile->transCntrChng = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3047,6 +3097,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||||
*(int*)pArg = ((unixFile*)id)->lastErrno;
|
*(int*)pArg = ((unixFile*)id)->lastErrno;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
case SQLITE_FCNTL_CHUNK_SIZE: {
|
||||||
|
((unixFile*)id)->szChunk = *(int *)pArg;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
case SQLITE_FCNTL_SIZE_HINT: {
|
case SQLITE_FCNTL_SIZE_HINT: {
|
||||||
#if 0 /* No performance advantage seen on Linux */
|
#if 0 /* No performance advantage seen on Linux */
|
||||||
sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
|
sqlite3_int64 szFile = *(sqlite3_int64*)pArg;
|
||||||
|
|
|
@ -696,6 +696,7 @@ struct sqlite3_io_methods {
|
||||||
#define SQLITE_SET_LOCKPROXYFILE 3
|
#define SQLITE_SET_LOCKPROXYFILE 3
|
||||||
#define SQLITE_LAST_ERRNO 4
|
#define SQLITE_LAST_ERRNO 4
|
||||||
#define SQLITE_FCNTL_SIZE_HINT 5
|
#define SQLITE_FCNTL_SIZE_HINT 5
|
||||||
|
#define SQLITE_FCNTL_CHUNK_SIZE 6
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Mutex Handle
|
** CAPI3REF: Mutex Handle
|
||||||
|
|
39
src/test1.c
39
src/test1.c
|
@ -4613,6 +4613,44 @@ static int file_control_lasterrno_test(
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** tclcmd: file_control_chunksize_test DB DBNAME SIZE
|
||||||
|
**
|
||||||
|
** This TCL command runs the sqlite3_file_control interface and
|
||||||
|
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
|
||||||
|
** SQLITE_SET_LOCKPROXYFILE verbs.
|
||||||
|
*/
|
||||||
|
static int file_control_chunksize_test(
|
||||||
|
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||||
|
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||||
|
int objc, /* Number of arguments */
|
||||||
|
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||||
|
){
|
||||||
|
int nSize; /* New chunk size */
|
||||||
|
char *zDb; /* Db name ("main", "temp" etc.) */
|
||||||
|
sqlite3 *db; /* Database handle */
|
||||||
|
int rc; /* file_control() return code */
|
||||||
|
|
||||||
|
if( objc!=4 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
|
||||||
|
|| Tcl_GetIntFromObj(interp, objv[3], &nSize)
|
||||||
|
){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
zDb = Tcl_GetString(objv[2]);
|
||||||
|
if( zDb[0]=='\0' ) zDb = NULL;
|
||||||
|
|
||||||
|
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
|
||||||
|
if( rc ){
|
||||||
|
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** tclcmd: file_control_lockproxy_test DB PWD
|
** tclcmd: file_control_lockproxy_test DB PWD
|
||||||
**
|
**
|
||||||
|
@ -5106,6 +5144,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||||
{ "file_control_test", file_control_test, 0 },
|
{ "file_control_test", file_control_test, 0 },
|
||||||
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
|
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
|
||||||
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
|
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
|
||||||
|
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
|
||||||
{ "sqlite3_vfs_list", vfs_list, 0 },
|
{ "sqlite3_vfs_list", vfs_list, 0 },
|
||||||
|
|
||||||
/* Functions from os.h */
|
/* Functions from os.h */
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
# 2010 July 28
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
if {$::tcl_platform(platform)!="unix"} {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file_control_chunksize_test db main [expr 1024*1024]
|
||||||
|
|
||||||
|
do_test fallocate-1.1 {
|
||||||
|
execsql {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
PRAGMA auto_vacuum = 1;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
}
|
||||||
|
file size test.db
|
||||||
|
} [expr 1*1024*1024]
|
||||||
|
|
||||||
|
do_test fallocate-1.2 {
|
||||||
|
execsql { INSERT INTO t1 VALUES(1, zeroblob(1024*900)) }
|
||||||
|
file size test.db
|
||||||
|
} [expr 1*1024*1024]
|
||||||
|
|
||||||
|
do_test fallocate-1.3 {
|
||||||
|
execsql { INSERT INTO t1 VALUES(2, zeroblob(1024*900)) }
|
||||||
|
file size test.db
|
||||||
|
} [expr 2*1024*1024]
|
||||||
|
|
||||||
|
do_test fallocate-1.4 {
|
||||||
|
execsql { DELETE FROM t1 WHERE a = 1 }
|
||||||
|
file size test.db
|
||||||
|
} [expr 1*1024*1024]
|
||||||
|
|
||||||
|
do_test fallocate-1.5 {
|
||||||
|
execsql { DELETE FROM t1 WHERE a = 2 }
|
||||||
|
file size test.db
|
||||||
|
} [expr 1*1024*1024]
|
||||||
|
|
||||||
|
do_test fallocate-1.6 {
|
||||||
|
execsql { PRAGMA freelist_count }
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
finish_test
|
Loading…
Reference in New Issue