Cherry-pick the multi-file transaction fix for ticket [f3e5abed55] out of

the experimental branch.

FossilOrigin-Name: 40f7f0a583e6bba66cd006253a0ef4623ea74f17
This commit is contained in:
drh 2010-07-30 11:20:35 +00:00
parent 3843a4c19a
commit abfb62f9bd
6 changed files with 161 additions and 14 deletions

View File

@ -1,5 +1,8 @@
C Add\stests\sto\scheck\sthat\sthe\sICU\sregexp()\sfunction\scan\sonly\sbe\scalled\swith\sexactly\stwo\sarguments.
D 2010-07-30T05:06:05
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Cherry-pick\sthe\smulti-file\stransaction\sfix\sfor\sticket\s[f3e5abed55]\sout\sof\nthe\sexperimental\sbranch.
D 2010-07-30T11:20:36
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -156,8 +159,8 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248
F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
F src/pager.c 33117640d8e0058dbf705b95e20ebf246cbb4bc1
F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
F src/pager.c d559cc0bb784fe5f5b812b2bc2329f09231515a5
F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
@ -222,7 +225,7 @@ F src/vdbe.c cefff41564b68a412e65e6a1013ec1b1c1ece6c4
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
F src/vdbeInt.h ffd68c4d4229227a5089bec53a1c635146177abc
F src/vdbeapi.c d0f4407e465f261780ad725c1caece7d66a6aa35
F src/vdbeaux.c 77442ab4233858cf603910429033fbbd997ecdef
F src/vdbeaux.c 8a443e73760ca65ffdfda3e26df4c8c90eeefa11
F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
@ -645,6 +648,7 @@ F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-cbd054fa6b.test f14f97ea43662e6f70c9e63287081e8be5d9d589
F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
F test/tkt-d82e3f3721.test 731359dfdcdb36fea0559cd33fec39dd0ceae8e6
F test/tkt-f3e5abed55.test 91713833e266fbdc60f2030e05647ad4762073f6
F test/tkt-f777251dc7a.test 6f24c053bc5cdb7e1e19be9a72c8887cf41d5e87
F test/tkt-f973c7ac31.test 1da0ed15ec2c7749fb5ce2828cd69d07153ad9f4
F test/tkt-fc62af4523.test 72825d3febdedcd5593a27989fc05accdbfc2bb4
@ -839,7 +843,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P d37443d33388b402e610a00c362a1e2e79548801
R 1df44901de4b741a545cdb85506640b4
U dan
Z 47b66d0e2bb0d61fe912692f971ceef4
P 451d965742cc219db709939b4ba1da2f2343dbce
R b0221ec16dca16ffff1bd5b40fa2847e
U drh
Z 3292246f79754c1a33410d74f4888b7e
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMUrWIoxKgR168RlERAgl9AJ9pHsRDtGgzTlt5S8NSiNWiQ7ew2QCdH2kx
84Gf1zkCE4fUgXSzHJvHTGU=
=LLzG
-----END PGP SIGNATURE-----

View File

@ -1 +1 @@
451d965742cc219db709939b4ba1da2f2343dbce
40f7f0a583e6bba66cd006253a0ef4623ea74f17

View File

@ -5061,6 +5061,26 @@ int sqlite3PagerSync(Pager *pPager){
return rc;
}
/*
** This function may only be called while a write-transaction is active in
** rollback. If the connection is in WAL mode, this call is a no-op.
** Otherwise, if the connection does not already have an EXCLUSIVE lock on
** the database file, an attempt is made to obtain one.
**
** If the EXCLUSIVE lock is already held or the attempt to obtain it is
** successful, or the connection is in WAL mode, SQLITE_OK is returned.
** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is
** returned.
*/
int sqlite3PagerExclusiveLock(Pager *pPager){
int rc = SQLITE_OK;
assert( pPager->state>=PAGER_RESERVED );
if( 0==pagerUseWal(pPager) ){
rc = pager_wait_on_lock(pPager, PAGER_EXCLUSIVE);
}
return rc;
}
/*
** Sync the database file for the pager pPager. zMaster points to the name
** of a master journal file that should be written into the individual

View File

@ -129,6 +129,7 @@ void *sqlite3PagerGetExtra(DbPage *);
int sqlite3PagerPagecount(Pager*, int*);
int sqlite3PagerBegin(Pager*, int exFlag, int);
int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
int sqlite3PagerExclusiveLock(Pager*);
int sqlite3PagerSync(Pager *pPager);
int sqlite3PagerCommitPhaseTwo(Pager*);
int sqlite3PagerRollback(Pager*);

View File

@ -1646,9 +1646,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** to the transaction.
*/
rc = sqlite3VtabSync(db, &p->zErrMsg);
if( rc!=SQLITE_OK ){
return rc;
}
/* This loop determines (a) if the commit hook should be invoked and
** (b) how many database files have open write transactions, not
@ -1656,13 +1653,17 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** one database file has an open write transaction, a master journal
** file is required for an atomic commit.
*/
for(i=0; i<db->nDb; i++){
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeIsInTrans(pBt) ){
needXcommit = 1;
if( i!=1 ) nTrans++;
rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
}
}
if( rc!=SQLITE_OK ){
return rc;
}
/* If there are any write-transactions at all, invoke the commit hook */
if( needXcommit && db->xCommitCallback ){
@ -1801,6 +1802,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
}
}
sqlite3OsCloseFree(pMaster);
assert( rc!=SQLITE_BUSY );
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, zMaster);
return rc;

113
test/tkt-f3e5abed55.test Normal file
View File

@ -0,0 +1,113 @@
# 2010 July 29
#
# 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
source $testdir/malloc_common.tcl
foreach f [glob -nocomplain test.db*mj*] { file delete -force $f }
file delete -force test.db2
do_test tkt-f3e5abed55-1.1 {
execsql {
ATTACH 'test.db2' AS aux;
CREATE TABLE main.t1(a, b);
CREATE TABLE aux.t2(c, d);
}
} {}
do_test tkt-f3e5abed55-1.2 {
glob -nocomplain test.db*mj*
} {}
do_test tkt-f3e5abed55-1.3 {
sqlite3 db2 test.db
execsql { BEGIN; SELECT * FROM t1 } db2
} {}
do_test tkt-f3e5abed55-1.4 {
execsql {
BEGIN;
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t2 VALUES(1, 2);
}
catchsql COMMIT
} {1 {database is locked}}
do_test tkt-f3e5abed55-1.5 {
execsql COMMIT db2
execsql COMMIT
} {}
do_test tkt-f3e5abed55-1.6 {
glob -nocomplain test.db*mj*
} {}
foreach f [glob -nocomplain test.db*mj*] { file delete -force $f }
db close
db2 close
# Set up a testvfs so that the next time SQLite tries to delete the
# file "test.db-journal", a snapshot of the current file-system contents
# is taken.
#
testvfs tvfs -default 1
tvfs script xDelete
tvfs filter xDelete
proc xDelete {method file args} {
if {[file tail $file] == "test.db-journal"} {
faultsim_save
tvfs filter {}
}
return "SQLITE_OK"
}
sqlite3 db test.db
sqlite3 db2 test.db
do_test tkt-f3e5abed55-2.1 {
execsql {
ATTACH 'test.db2' AS aux;
BEGIN;
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t2 VALUES(3, 4);
}
} {}
do_test tkt-f3e5abed55-2.2 {
execsql { BEGIN; SELECT * FROM t1 } db2
} {1 2}
do_test tkt-f3e5abed55-2.3 {
catchsql COMMIT
} {1 {database is locked}}
do_test tkt-f3e5abed55-2.4 {
execsql COMMIT db2
execsql {
COMMIT;
SELECT * FROM t1;
SELECT * FROM t2;
}
} {1 2 3 4 1 2 3 4}
do_test tkt-f3e5abed55-2.5 {
db close
db2 close
faultsim_restore_and_reopen
execsql {
ATTACH 'test.db2' AS aux;
SELECT * FROM t1;
SELECT * FROM t2;
}
} {1 2 3 4 1 2 3 4}
finish_test