mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Fix SQLITE_DBSTATUS_SCHEMA_USED so that it works with SQLITE_OPEN_SHARED_SCHEMA connections.
FossilOrigin-Name: d43b3c056cb13930865c504c9498b2c83e4bebce9bff01ee21293e7dc7a6711e
This commit is contained in:
@@ -33,9 +33,9 @@ database is treated as empty. This usually means that corruption results in
|
||||
a "no such table: xxx" error instead of a more specific error message.
|
||||
|
||||
For SQLITE_OPEN_SHARED_SCHEMA connections, the
|
||||
SQLITE_DBSTATUS_SCHEMA_USED sqlite3_db_used() distributes
|
||||
the memory used for a shared schema object evenly between all database
|
||||
connections that share it.
|
||||
SQLITE_DBSTATUS_SCHEMA_USED sqlite3_db_status() verb
|
||||
distributes the memory used for a shared schema object evenly between all
|
||||
database connections that share it.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
|
24
manifest
24
manifest
@@ -1,5 +1,5 @@
|
||||
C Change\sthe\sname\sof\sthe\sSQLITE_OPEN_REUSE_SCHEMA\sflag\sto\sSQLITE_OPEN_SHARED_SCHEMA.
|
||||
D 2019-02-14T18:38:44.649
|
||||
C Fix\sSQLITE_DBSTATUS_SCHEMA_USED\sso\sthat\sit\sworks\swith\sSQLITE_OPEN_SHARED_SCHEMA\sconnections.
|
||||
D 2019-02-14T21:04:27.065
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 56456706c4da271309914c756c9c8ea537685f1c79f8785afa72f968d6810482
|
||||
@@ -39,7 +39,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
F doc/shared_schema.md 8659d89eaeab5547c435284e0356237df31beb30a7575f30d76d9bc0eb825f9d
|
||||
F doc/shared_schema.md 4c1ea0da3c9a83afe646c696f4402827b38134dbc73c1e0637adce6546cb2a79
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
|
||||
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||
@@ -459,8 +459,8 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 161b6a57b91d160065e512a4d0be180e402a16a059034a380cbdc2411924f8ac
|
||||
F src/btree.h 63b94fb38ce571c15eb6a3661815561b501d23d5948b2d1e951fbd7a2d04e8d3
|
||||
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
|
||||
F src/build.c 66830361a2d820e52c483bd5ac3af0fd111795fc7836d99cfdc8818dbfa23d5d
|
||||
F src/callback.c 8d0402ae92ba24b99b4af9abf6881821e78826a9cfe984b38dfbf7664804fea2
|
||||
F src/build.c 364c8fa52cca6002be42c987e7421bd38c40e0f3afdf3198bc174fb92da4f4e8
|
||||
F src/callback.c e60a0c3928adb5b5c8dffa3df2d1b34c67177b7c149c9d109012c22a631fc20a
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
|
||||
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
@@ -520,9 +520,9 @@ F src/shell.c.in d7d63fd1ecef44d19088adc188652252327eab782d59cf1958657943132b508
|
||||
F src/sqlite.h.in cd9b7c397b942a4903c46ebbabee47f920a9916e96e70e0b4f793076d4b45e31
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
|
||||
F src/sqliteInt.h 176ae22317dda2b49d9c3c28bf9215e7ae8f012f88c37dd505f6be8b3637db28
|
||||
F src/sqliteInt.h 0238a621a7d054370b6700c2d1368870cd2282f38a74f3ddafb238a8ea3c181c
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/status.c 0361d78dabfd2a92c740911f42723d2f6775d619feb8f8910827f9c9fe8bc30f
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c f11d822fb2bd6e155d41535a629d1c34daf3d98a37b1f0ea6b4cb11d150d3c57
|
||||
F src/test1.c 353b066e7ec761c4c715c1c20b888e0e7a0b0c0eda7f68c110e032d63713cade
|
||||
@@ -1229,7 +1229,7 @@ F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5e
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/reuse1.test 31c312375ccfcc5c2abc1fca5e4a89d6309c57ea6b1fa3179a5eee68016f9c74
|
||||
F test/reuse2.test 51a4ba225c602bf19847c27c5f0156c3f273f2c8de2456c22b97c2a9a3824d87
|
||||
F test/reuse3.test 3e865c031fe71242ebcdd90baf34cba8be4dddacad2fe025e697ecf035335f4a
|
||||
F test/reuse3.test b04e9b7115ece25b28ca57b42464e058cc0de35742b150840a5937c3ddb7ca8a
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6
|
||||
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
|
||||
@@ -1370,7 +1370,7 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90
|
||||
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 049da602775bebfadfa2fae0710e1099a38ef2fc9f76c7546be3ba8fdbb02263
|
||||
F test/tclsqlite.test 74cc8404f69e2c3aafbc9bc73a0e686aa91612b88284f9cfd868cb916b67f6b0
|
||||
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
|
||||
F test/tempdb2.test 2479226e4cb96f4c663eccd2d12c077cf6bda29ca5cc69a8a58a06127105dd62
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
@@ -1809,7 +1809,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P e47a5aea76560e86e5417fea9e2219ec6c30e47ef383e499cfe927f64d584dac
|
||||
R 8625b684c268ad69e5f2e6997ec316b6
|
||||
P 7257fcc8c990b46a4f6a9e506f4a4a40195e6b2c626efd380cfa01f0ce8eb0fb
|
||||
R 335d544fb33c769d2c93a5ba7269ae2c
|
||||
U dan
|
||||
Z 501ceb9c380b311fe8ede824c64ca859
|
||||
Z 4a0370c09441d299e3638aa59f7363a2
|
||||
|
@@ -1 +1 @@
|
||||
7257fcc8c990b46a4f6a9e506f4a4a40195e6b2c626efd380cfa01f0ce8eb0fb
|
||||
d43b3c056cb13930865c504c9498b2c83e4bebce9bff01ee21293e7dc7a6711e
|
@@ -294,7 +294,7 @@ int sqlite3UserAuthTable(const char *zTable){
|
||||
** Non-zero is returned if a schema is loaded, or zero if it was already
|
||||
** loaded when this function was called..
|
||||
*/
|
||||
static int loadSharableSchema(sqlite3 *db, int iDb){
|
||||
int sqlite3SchemaLoad(sqlite3 *db, int iDb){
|
||||
if( IsReuseSchema(db)
|
||||
&& DbHasProperty(db, iDb, DB_SchemaLoaded)==0
|
||||
&& (db->init.busy==0 || (iDb!=1 && db->init.iDb==1))
|
||||
@@ -341,7 +341,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
|
||||
int bUnload;
|
||||
assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
||||
bUnload = loadSharableSchema(db, j);
|
||||
bUnload = sqlite3SchemaLoad(db, j);
|
||||
p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
|
||||
if( p ) return p;
|
||||
if( bUnload ){
|
||||
@@ -398,7 +398,7 @@ Table *sqlite3LocateTable(
|
||||
pMod = sqlite3PragmaVtabRegister(db, zName);
|
||||
}
|
||||
if( pMod ){
|
||||
loadSharableSchema(db, 0);
|
||||
sqlite3SchemaLoad(db, 0);
|
||||
if( sqlite3VtabEponymousTableInit(pParse, pMod) ){
|
||||
return pMod->pEpoTab;
|
||||
}
|
||||
|
@@ -549,6 +549,28 @@ static SchemaPool *SQLITE_WSD schemaPoolList = 0;
|
||||
SchemaPool *sqlite3SchemaPoolList(void){ return schemaPoolList; }
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Database handle db was opened with the SHARED_SCHEMA flag, and database
|
||||
** iDb is currently connected to a schema-pool. When this function is called,
|
||||
** (*pnByte) is set to nInit plus the amount of memory used to store a
|
||||
** single instance of the Schema objects managed by the schema-pool.
|
||||
** This function adjusts (*pnByte) sot hat it is set to nInit plus
|
||||
** (nSchema/nRef) of the amount of memory used by a single Schema object,
|
||||
** where nSchema is the number of Schema objects allocated by this pool,
|
||||
** and nRef is the number of connections to the schema-pool.
|
||||
*/
|
||||
void sqlite3SchemaAdjustUsed(sqlite3 *db, int iDb, int nInit, int *pnByte){
|
||||
SchemaPool *pSPool = db->aDb[iDb].pSPool;
|
||||
int nSchema = 0;
|
||||
Schema *p;
|
||||
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
|
||||
for(p=pSPool->pSchema; p; p=p->pNext){
|
||||
nSchema++;
|
||||
}
|
||||
*pnByte = nInit + ((*pnByte - nInit) * nSchema) / pSPool->nRef;
|
||||
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
|
||||
}
|
||||
|
||||
/*
|
||||
** Check that the schema of db iDb is writable (either because it is the
|
||||
** temp db schema or because the db handle was opened without
|
||||
|
@@ -4325,8 +4325,10 @@ int sqlite3SchemaConnect(sqlite3*, int, u64);
|
||||
int sqlite3SchemaDisconnect(sqlite3 *, int, int);
|
||||
void sqlite3SchemaClearOrDisconnect(sqlite3*, int);
|
||||
Schema *sqlite3SchemaExtract(SchemaPool*);
|
||||
int sqlite3SchemaLoad(sqlite3*, int);
|
||||
void sqlite3SchemaReleaseAll(sqlite3*);
|
||||
void sqlite3SchemaRelease(sqlite3*, int);
|
||||
void sqlite3SchemaAdjustUsed(sqlite3*, int, int, int*);
|
||||
void sqlite3SchemaWritable(Parse*, int);
|
||||
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
|
||||
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
|
||||
|
15
src/status.c
15
src/status.c
@@ -275,11 +275,19 @@ int sqlite3_db_status(
|
||||
case SQLITE_DBSTATUS_SCHEMA_USED: {
|
||||
int i; /* Used to iterate through schemas */
|
||||
int nByte = 0; /* Used to accumulate return value */
|
||||
int bReleaseSchema;
|
||||
|
||||
sqlite3BtreeEnterAll(db);
|
||||
bReleaseSchema = sqlite3LockReusableSchema(db);
|
||||
db->pnBytesFreed = &nByte;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Schema *pSchema = db->aDb[i].pSchema;
|
||||
int bUnload = 0;
|
||||
int nUsed = nByte;
|
||||
Schema *pSchema;
|
||||
if( db->aDb[i].pSPool ){
|
||||
bUnload = sqlite3SchemaLoad(db, i);
|
||||
}
|
||||
pSchema = db->aDb[i].pSchema;
|
||||
if( ALWAYS(pSchema!=0) ){
|
||||
HashElem *p;
|
||||
|
||||
@@ -301,7 +309,12 @@ int sqlite3_db_status(
|
||||
sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
|
||||
}
|
||||
}
|
||||
if( db->aDb[i].pSPool ){
|
||||
if( bUnload ) sqlite3SchemaRelease(db, i);
|
||||
sqlite3SchemaAdjustUsed(db, i, nUsed, &nByte);
|
||||
}
|
||||
}
|
||||
sqlite3UnlockReusableSchema(db, bReleaseSchema);
|
||||
db->pnBytesFreed = 0;
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
|
||||
|
@@ -88,5 +88,41 @@ do_catchsql_test 2.2 {
|
||||
SELECT * FROM x1;
|
||||
} {1 {no such table: x1}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE x1(a, b, c);
|
||||
CREATE INDEX i1 ON x1(a, b, c);
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
|
||||
SELECT 1, 2, 3, 4, 5;
|
||||
END;
|
||||
INSERT INTO x1 VALUES(1, 2, 3);
|
||||
}
|
||||
sqlite3 db1 test.db -shared-schema 1
|
||||
|
||||
do_test 3.1 {
|
||||
execsql { SELECT * FROM x1 } db1
|
||||
set N [lindex [sqlite3_db_status db1 SCHEMA_USED 0] 1]
|
||||
expr $N==$N
|
||||
} 1
|
||||
|
||||
sqlite3 db2 test.db -shared-schema 1
|
||||
do_test 3.2 {
|
||||
execsql { SELECT * FROM x1 } db2
|
||||
breakpoint
|
||||
set N2 [lindex [sqlite3_db_status db2 SCHEMA_USED 0] 1]
|
||||
expr $N2>($N/2) && $N2<($N/2)+400
|
||||
} 1
|
||||
|
||||
sqlite3 db3 test.db -shared-schema 1
|
||||
sqlite3 db4 test.db -shared-schema 1
|
||||
do_test 3.3 {
|
||||
execsql { SELECT * FROM x1 } db3
|
||||
execsql { SELECT * FROM x1 } db4
|
||||
set N4 [lindex [sqlite3_db_status db2 SCHEMA_USED 0] 1]
|
||||
set M [expr 2*($N-$N2)]
|
||||
expr {$N4 == (($M / 4) + $N-$M)}
|
||||
} 1
|
||||
|
||||
finish_test
|
||||
|
||||
|
@@ -24,7 +24,7 @@ source $testdir/tester.tcl
|
||||
|
||||
# Check the error messages generated by tclsqlite
|
||||
#
|
||||
set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN? ?-reuse-schema BOOLEAN?"
|
||||
set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN? ?-shared-schema BOOLEAN?"
|
||||
if {[sqlite3 -has-codec]} {
|
||||
append r " ?-key CODECKEY?"
|
||||
}
|
||||
|
Reference in New Issue
Block a user