1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Avoid creating a master journal unless two or more databases in the

transaction can actually benefit from that master journal.

FossilOrigin-Name: 3ed1890612bd45bd9c72f670d2cbb0b8fbd35d92
This commit is contained in:
drh
2016-02-22 14:57:38 +00:00
parent e872d5133d
commit 8e6cf0a7c5
4 changed files with 105 additions and 29 deletions

View File

@ -1,5 +1,5 @@
C Change\smagic\snumbers\sassociated\swith\ssynchronous\ssettings\sto\snamed\sconstants. C Avoid\screating\sa\smaster\sjournal\sunless\stwo\sor\smore\sdatabases\sin\sthe\ntransaction\scan\sactually\sbenefit\sfrom\sthat\smaster\sjournal.
D 2016-02-22T13:23:16.525 D 2016-02-22T14:57:38.065
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142 F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 28fc4ee02333996d31b3602b39eeb8e609a89ce4 F Makefile.msc 28fc4ee02333996d31b3602b39eeb8e609a89ce4
@ -418,7 +418,7 @@ F src/vdbe.c 822e44c1dd859794f8c414e8bae4d96ac1fa774d
F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512 F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
F src/vdbeInt.h 581e5bff9a401fabdb917b816503cda7356ec3e1 F src/vdbeInt.h 581e5bff9a401fabdb917b816503cda7356ec3e1
F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009
F src/vdbeaux.c ec9a4d939a7430b76f53c5ef5cdbca3c8704848a F src/vdbeaux.c 51aaf15e5c29512423429cc0e0477e08f7181514
F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db
F src/vdbemem.c be8381ed6de54eb9cb9dfa802823cdeb5166d855 F src/vdbemem.c be8381ed6de54eb9cb9dfa802823cdeb5166d855
F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
@ -932,7 +932,7 @@ F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager1.test f49df1a8b0e38b9ee3a7dd2ab4d427507b7314ce
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
@ -1429,7 +1429,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598 F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P a48ac4c347813bd2b416b1cb06c3cbf1f4b3781a P 9230ba6c01f4a550d92a0cbbf36dbe81af14fbfc
R 5ba950defec5ebb5c806c723cbc4f5b9 R 28c7602ad1de5114aacb14204e4f7226
U drh U drh
Z 3422238b7807aea6814e5b393b012e9d Z aad5fe626dac38bb4fd331764966d6a1

View File

@ -1 +1 @@
9230ba6c01f4a550d92a0cbbf36dbe81af14fbfc 3ed1890612bd45bd9c72f670d2cbb0b8fbd35d92

View File

@ -2155,7 +2155,9 @@ int sqlite3VdbeSetColName(
*/ */
static int vdbeCommit(sqlite3 *db, Vdbe *p){ static int vdbeCommit(sqlite3 *db, Vdbe *p){
int i; int i;
int nTrans = 0; /* Number of databases with an active write-transaction */ int nTrans = 0; /* Number of databases with an active write-transaction
** that are candidates for a two-phase commit using a
** master-journal */
int rc = SQLITE_OK; int rc = SQLITE_OK;
int needXcommit = 0; int needXcommit = 0;
@ -2183,10 +2185,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt; Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeIsInTrans(pBt) ){ if( sqlite3BtreeIsInTrans(pBt) ){
/* Whether or not a database might need a master journal depends upon
** its journal mode (among other things). This matrix determines which
** journal modes use a master journal and which do not */
static const u8 aMJNeeded[] = {
/* DELETE */ 1,
/* PERSIST */ 1,
/* OFF */ 0,
/* TRUNCATE */ 1,
/* MEMORY */ 0,
/* WAL */ 0
};
Pager *pPager; /* Pager associated with pBt */
needXcommit = 1; needXcommit = 1;
if( i!=1 ) nTrans++;
sqlite3BtreeEnter(pBt); sqlite3BtreeEnter(pBt);
rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt)); pPager = sqlite3BtreePager(pBt);
if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
&& aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
){
assert( i!=1 );
nTrans++;
}
rc = sqlite3PagerExclusiveLock(pPager);
sqlite3BtreeLeave(pBt); sqlite3BtreeLeave(pBt);
} }
} }

View File

@ -529,6 +529,7 @@ set pwd [get_pwd]
testvfs tv -default 1 testvfs tv -default 1
tv script copy_on_mj_delete tv script copy_on_mj_delete
set ::mj_filename_length 0 set ::mj_filename_length 0
set ::mj_delete_cnt 0
proc copy_on_mj_delete {method filename args} { proc copy_on_mj_delete {method filename args} {
if {[string match *mj* [file tail $filename]]} { if {[string match *mj* [file tail $filename]]} {
# #
@ -542,6 +543,7 @@ proc copy_on_mj_delete {method filename args} {
set ::mj_filename_length [string length $filename] set ::mj_filename_length [string length $filename]
} }
faultsim_save faultsim_save
incr ::mj_delete_cnt
} }
return SQLITE_OK return SQLITE_OK
} }
@ -579,29 +581,68 @@ foreach {tn1 tcl} {
} }
} { } {
eval $tcl eval $tcl
foreach {tn2 sql} { foreach {tn2 sql usesMJ} {
o { o {
PRAGMA main.synchronous=OFF; PRAGMA main.synchronous=OFF;
PRAGMA aux.synchronous=OFF; PRAGMA aux.synchronous=OFF;
PRAGMA journal_mode = DELETE; PRAGMA journal_mode = DELETE;
} } 0
o512 { o512 {
PRAGMA main.synchronous=OFF; PRAGMA main.synchronous=OFF;
PRAGMA aux.synchronous=OFF; PRAGMA aux.synchronous=OFF;
PRAGMA main.page_size = 512; PRAGMA main.page_size = 512;
PRAGMA aux.page_size = 512; PRAGMA aux.page_size = 512;
PRAGMA journal_mode = DELETE; PRAGMA journal_mode = DELETE;
} } 0
n { n {
PRAGMA main.synchronous=NORMAL; PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL; PRAGMA aux.synchronous=NORMAL;
PRAGMA journal_mode = DELETE; PRAGMA journal_mode = DELETE;
} } 1
f { f {
PRAGMA main.synchronous=FULL; PRAGMA main.synchronous=FULL;
PRAGMA aux.synchronous=FULL; PRAGMA aux.synchronous=FULL;
PRAGMA journal_mode = DELETE; PRAGMA journal_mode = DELETE;
} } 1
w1 {
PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL;
PRAGMA journal_mode = WAL;
} 0
w2 {
PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL;
PRAGMA main.journal_mode=DELETE;
PRAGMA aux.journal_mode=WAL;
} 0
o1a {
PRAGMA main.synchronous=FULL;
PRAGMA aux.synchronous=OFF;
PRAGMA journal_mode=DELETE;
} 0
o1b {
PRAGMA main.synchronous=OFF;
PRAGMA aux.synchronous=NORMAL;
PRAGMA journal_mode=DELETE;
} 0
m1 {
PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL;
PRAGMA main.journal_mode=DELETE;
PRAGMA aux.journal_mode = MEMORY;
} 0
t1 {
PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL;
PRAGMA main.journal_mode=DELETE;
PRAGMA aux.journal_mode = TRUNCATE;
} 1
p1 {
PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL;
PRAGMA main.journal_mode=DELETE;
PRAGMA aux.journal_mode = PERSIST;
} 1
} { } {
set tn "${tn1}.${tn2}" set tn "${tn1}.${tn2}"
@ -613,6 +654,7 @@ foreach {tn1 tcl} {
# #
tv filter xDelete tv filter xDelete
do_test pager1-4.4.$tn.1 { do_test pager1-4.4.$tn.1 {
set ::mj_delete_cnt 0
faultsim_delete_and_reopen $prefix faultsim_delete_and_reopen $prefix
execsql " execsql "
ATTACH '${prefix}2' AS aux; ATTACH '${prefix}2' AS aux;
@ -634,6 +676,13 @@ foreach {tn1 tcl} {
} }
} {} } {}
tv filter {} tv filter {}
# Verify that a master journal was deleted only for those cases where
# master journals really ought to be used
#
do_test pager1-4.4.$tn.1b {
set ::mj_delete_cnt
} $usesMJ
# Check that the transaction was committed successfully. # Check that the transaction was committed successfully.
# #
@ -644,25 +693,33 @@ foreach {tn1 tcl} {
SELECT * FROM b SELECT * FROM b
} {won too free double-you why zed} } {won too free double-you why zed}
# Restore the file-system and reopen the databases. Check that it now if {$usesMJ} {
# appears that the transaction was not committed (because the file-system # Restore the file-system and reopen the databases. Check that it now
# was restored to the state where it had not been). # appears that the transaction was not committed (because the file-system
# # was restored to the state where it had not been).
do_test pager1-4.4.$tn.4 { #
faultsim_restore_and_reopen $prefix do_test pager1-4.4.$tn.4 {
execsql "ATTACH '${prefix}2' AS aux" faultsim_restore_and_reopen $prefix
} {} execsql "ATTACH '${prefix}2' AS aux"
do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed} } {}
do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free} do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
}
# Restore the file-system again. This time, before reopening the databases, # Restore the file-system again. This time, before reopening the databases,
# delete the master-journal file from the file-system. It now appears that # delete the master-journal file from the file-system. It now appears that
# the transaction was committed (no master-journal file == no rollback). # the transaction was committed (no master-journal file == no rollback).
# #
do_test pager1-4.4.$tn.7 { do_test pager1-4.4.$tn.7 {
faultsim_restore_and_reopen $prefix if {$::mj_delete_cnt>0} {
foreach f [glob ${prefix}-mj*] { forcedelete $f } faultsim_restore_and_reopen $prefix
foreach f [glob ${prefix}-mj*] { forcedelete $f }
} else {
db close
sqlite3 db $prefix
}
execsql "ATTACH '${prefix}2' AS aux" execsql "ATTACH '${prefix}2' AS aux"
glob -nocomplain ${prefix}-mj*
} {} } {}
do_execsql_test pager1-4.4.$tn.8 { do_execsql_test pager1-4.4.$tn.8 {
SELECT * FROM a SELECT * FROM a
@ -678,7 +735,6 @@ db close
tv delete tv delete
forcedelete $dirname forcedelete $dirname
# Set up a VFS to make a copy of the file-system just before deleting a # Set up a VFS to make a copy of the file-system just before deleting a
# journal file to commit a transaction. The transaction modifies exactly # journal file to commit a transaction. The transaction modifies exactly
# two database pages (and page 1 - the change counter). # two database pages (and page 1 - the change counter).