mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Disallow attaching the same database multiple times to the same db connection
in shared cache mode, since doing so leads to deadlock. (CVS 6578) FossilOrigin-Name: 715f14f1dcaf604d4794bf3e18e245d4f8c5d5a9
This commit is contained in:
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\sapparent\stypo\son\sexclusive.test\sin\sthe\s(6575)\scheck-in.\s(CVS\s6577)
|
C Disallow\sattaching\sthe\ssame\sdatabase\smultiple\stimes\sto\sthe\ssame\sdb\sconnection\nin\sshared\scache\smode,\ssince\sdoing\sso\sleads\sto\sdeadlock.\s(CVS\s6578)
|
||||||
D 2009-04-30T12:25:59
|
D 2009-04-30T13:30:33
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -101,12 +101,12 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
|||||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||||
F src/alter.c 8ab5824bde0a03dae5829f61557ab7c72757000a
|
F src/alter.c 8ab5824bde0a03dae5829f61557ab7c72757000a
|
||||||
F src/analyze.c e239496cfb5394ac8867f1c112905ddab8d01cd9
|
F src/analyze.c e239496cfb5394ac8867f1c112905ddab8d01cd9
|
||||||
F src/attach.c 2acdbf4bbca681405a3fd3b1c75356be10becb62
|
F src/attach.c 5e4c387144503013963bac9c7b2f07e22bcbb3ee
|
||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
|
F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
|
||||||
F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
|
F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
|
||||||
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
||||||
F src/btree.c 2b89d1f578c417d68befd801a1291836c923bd1e
|
F src/btree.c 2165bfef1b4bb90a84565c63ae06cad2954d1d3c
|
||||||
F src/btree.h 99fcc7e8c4a1e35afe271bcb38de1a698dfc904e
|
F src/btree.h 99fcc7e8c4a1e35afe271bcb38de1a698dfc904e
|
||||||
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
|
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
|
||||||
F src/build.c dca0ad77c88cb00f6a11cc080a4f3285672cfa37
|
F src/build.c dca0ad77c88cb00f6a11cc080a4f3285672cfa37
|
||||||
@ -539,6 +539,7 @@ F test/shared2.test 8973e41e008acbbd8d1b191b91a23cd472f058e8
|
|||||||
F test/shared3.test 9c880afc081d797da514ef64bccf36f3fce2f09c
|
F test/shared3.test 9c880afc081d797da514ef64bccf36f3fce2f09c
|
||||||
F test/shared4.test d0fadacb50bb6981b2fb9dc6d1da30fa1edddf83
|
F test/shared4.test d0fadacb50bb6981b2fb9dc6d1da30fa1edddf83
|
||||||
F test/shared6.test db3906045175debea4a0d57cb94c6ffe2d85413d
|
F test/shared6.test db3906045175debea4a0d57cb94c6ffe2d85413d
|
||||||
|
F test/shared7.test 8114027cb5e8c376e467115703d46e5ac4e77739
|
||||||
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
|
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
|
||||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||||
@ -725,7 +726,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
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
|
||||||
P aa29a14ca040db25dadbca787aa75be3b7588415
|
P 95d22405e096355ce815cdb0908c4ef04107b490
|
||||||
R e5ecfcd2438204c7aa2bbe68cbf44244
|
R 8d3121c371bc6b3d2bb493dbba26f385
|
||||||
U drh
|
U drh
|
||||||
Z 7902f9496a68bca062f4a84f7c5dfe66
|
Z a41c8b6fc921420eb6f0176ff357b69b
|
||||||
|
@ -1 +1 @@
|
|||||||
95d22405e096355ce815cdb0908c4ef04107b490
|
715f14f1dcaf604d4794bf3e18e245d4f8c5d5a9
|
10
src/attach.c
10
src/attach.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||||
**
|
**
|
||||||
** $Id: attach.c,v 1.87 2009/04/30 05:40:34 drh Exp $
|
** $Id: attach.c,v 1.88 2009/04/30 13:30:33 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ static void attachFunc(
|
|||||||
if( aNew==0 ) return;
|
if( aNew==0 ) return;
|
||||||
}
|
}
|
||||||
db->aDb = aNew;
|
db->aDb = aNew;
|
||||||
aNew = &db->aDb[db->nDb++];
|
aNew = &db->aDb[db->nDb];
|
||||||
memset(aNew, 0, sizeof(*aNew));
|
memset(aNew, 0, sizeof(*aNew));
|
||||||
|
|
||||||
/* Open the database file. If the btree is successfully opened, use
|
/* Open the database file. If the btree is successfully opened, use
|
||||||
@ -129,7 +129,11 @@ static void attachFunc(
|
|||||||
rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
|
rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
|
||||||
db->openFlags | SQLITE_OPEN_MAIN_DB,
|
db->openFlags | SQLITE_OPEN_MAIN_DB,
|
||||||
&aNew->pBt);
|
&aNew->pBt);
|
||||||
if( rc==SQLITE_OK ){
|
db->nDb++;
|
||||||
|
if( rc==SQLITE_CONSTRAINT ){
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
zErrDyn = sqlite3MPrintf(db, "database is already attached");
|
||||||
|
}else if( rc==SQLITE_OK ){
|
||||||
Pager *pPager;
|
Pager *pPager;
|
||||||
aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
|
aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
|
||||||
if( !aNew->pSchema ){
|
if( !aNew->pSchema ){
|
||||||
|
19
src/btree.c
19
src/btree.c
@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.601 2009/04/30 09:10:38 danielk1977 Exp $
|
** $Id: btree.c,v 1.602 2009/04/30 13:30:33 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@ -1401,6 +1401,12 @@ static int btreeInvokeBusyHandler(void *pArg){
|
|||||||
** database file will be deleted when sqlite3BtreeClose() is called.
|
** database file will be deleted when sqlite3BtreeClose() is called.
|
||||||
** If zFilename is ":memory:" then an in-memory database is created
|
** If zFilename is ":memory:" then an in-memory database is created
|
||||||
** that is automatically destroyed when it is closed.
|
** that is automatically destroyed when it is closed.
|
||||||
|
**
|
||||||
|
** If the database is already opened in the same database connection
|
||||||
|
** and we are in shared cache mode, then the open will fail with an
|
||||||
|
** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared
|
||||||
|
** objects in the same database connection since doing so will lead
|
||||||
|
** to problems with locking.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeOpen(
|
int sqlite3BtreeOpen(
|
||||||
const char *zFilename, /* Name of the file containing the BTree database */
|
const char *zFilename, /* Name of the file containing the BTree database */
|
||||||
@ -1466,6 +1472,17 @@ int sqlite3BtreeOpen(
|
|||||||
assert( pBt->nRef>0 );
|
assert( pBt->nRef>0 );
|
||||||
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
|
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
|
||||||
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
|
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
|
||||||
|
int iDb;
|
||||||
|
for(iDb=db->nDb-1; iDb>=0; iDb--){
|
||||||
|
Btree *pExisting = db->aDb[iDb].pBt;
|
||||||
|
if( pExisting && pExisting->pBt==pBt ){
|
||||||
|
sqlite3_mutex_leave(mutexShared);
|
||||||
|
sqlite3_mutex_leave(mutexOpen);
|
||||||
|
sqlite3_free(zFullPathname);
|
||||||
|
sqlite3_free(p);
|
||||||
|
return SQLITE_CONSTRAINT;
|
||||||
|
}
|
||||||
|
}
|
||||||
p->pBt = pBt;
|
p->pBt = pBt;
|
||||||
pBt->nRef++;
|
pBt->nRef++;
|
||||||
break;
|
break;
|
||||||
|
55
test/shared7.test
Normal file
55
test/shared7.test
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# 2009 April 30
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# Make sure that attaching the same database multiple times in
|
||||||
|
# shared cache mode fails.
|
||||||
|
#
|
||||||
|
# $Id: shared7.test,v 1.1 2009/04/30 13:30:33 drh Exp $
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
ifcapable !shared_cache { finish_test ; return }
|
||||||
|
|
||||||
|
do_test shared7-1.1 {
|
||||||
|
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
|
||||||
|
sqlite3_enable_shared_cache
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_test shared7-1.2 {
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
db eval {
|
||||||
|
CREATE TABLE t1(x);
|
||||||
|
}
|
||||||
|
catchsql {
|
||||||
|
ATTACH 'test.db' AS err1;
|
||||||
|
}
|
||||||
|
} {1 {database is already attached}}
|
||||||
|
|
||||||
|
do_test shared7-1.3 {
|
||||||
|
file delete -force test2.db test2.db-journal
|
||||||
|
db eval {
|
||||||
|
ATTACH 'test2.db' AS test2;
|
||||||
|
CREATE TABLE test2.t2(y);
|
||||||
|
}
|
||||||
|
catchsql {
|
||||||
|
ATTACH 'test2.db' AS err2;
|
||||||
|
}
|
||||||
|
} {1 {database is already attached}}
|
||||||
|
do_test shared7-1.4 {
|
||||||
|
catchsql {
|
||||||
|
ATTACH 'test.db' AS err1;
|
||||||
|
}
|
||||||
|
} {1 {database is already attached}}
|
||||||
|
|
||||||
|
|
||||||
|
sqlite3_enable_shared_cache $::enable_shared_cache
|
||||||
|
finish_test
|
Reference in New Issue
Block a user