Fix a problem with rolling back hot journals using the unix-dotfile VFS.

FossilOrigin-Name: a44703135e8dd3cc67e548e1aa3c42e71df127fb7b593ccfc06025ec42a501fd
This commit is contained in:
dan 2024-06-12 15:50:35 +00:00
commit 718c5ff551
4 changed files with 107 additions and 33 deletions

View File

@ -1,5 +1,5 @@
C OPFS\sVFS:\schange\sthe\sxCheckReservedLock()\simpl\sto\salways\sreturn\sfalse,\sas\sdiscussed\sin\s[forum:a2f573b00cda1372|forum\sthread\sa2f573b00cda1372].\sThis\sdoes\snot\simpact\sany\scurrent\stests,\sand\smay\shave\sno\sdirect\simpact\sat\sall\sbecause\sof\show\sthat\sVFS\shandles\slocking,\sbut\sis\shypothetically\sa\smore\scorrect\ssolution\sthan\sthe\sprevious\sone.
D 2024-06-12T12:36:02.582
C Fix\sa\sproblem\swith\srolling\sback\shot\sjournals\susing\sthe\sunix-dotfile\sVFS.
D 2024-06-12T15:50:35.035
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -739,7 +739,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c 08ca53844f4bf8eafb18b0a9076c84afac41da912315a5cfbe9e704d4c10c090
F src/os_unix.c 2ea8d3ed496b8d1f9332a9505653424e5464fd797ea9d91f8e2e62f9dd0298d0
F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56
@ -1388,7 +1388,7 @@ F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8
F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38
F test/lock5.test 626571313daef2c949ce002f861042d63d81119fa62a9e999721c8bbd85e1ec9
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413
@ -2195,8 +2195,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 587ed3a5d283898ad0e67ccee86a0a4ccc432fa292c0a3534e9e6ec70a7b7780
R 627383e1e012584141ebd74c98bd7f4d
U stephan
Z 9f8d8dcb26b9598cd7f1252d2913b583
P c298b8ba2dcd01fa28b79a78bb4986fa0282755a0a36b7f38b93096ac31f521e 9d63033bf46ddf0f4d9d4ef06d56357fe6165f2370cd19cf81c2f7f61ce224fc
R 0f0b01c177eceb54a303d16754d756ef
T +closed 9d63033bf46ddf0f4d9d4ef06d56357fe6165f2370cd19cf81c2f7f61ce224fc
U dan
Z 25990fbb14d7309dc028769ec3a0c054
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
c298b8ba2dcd01fa28b79a78bb4986fa0282755a0a36b7f38b93096ac31f521e
a44703135e8dd3cc67e548e1aa3c42e71df127fb7b593ccfc06025ec42a501fd

View File

@ -2279,26 +2279,22 @@ static int nolockClose(sqlite3_file *id) {
/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, set *pResOut
** to a non-zero value otherwise *pResOut is set to zero. The return value
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
**
** In dotfile locking, either a lock exists or it does not. So in this
** variation of CheckReservedLock(), *pResOut is set to true if any lock
** is held on the file and false if the file is unlocked.
** file by this or any other process. If the caller holds a SHARED
** or greater lock when it is called, then it is assumed that no other
** client may hold RESERVED. Or, if the caller holds no lock, then it
** is assumed another client holds RESERVED if the lock-file exists.
*/
static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
int rc = SQLITE_OK;
int reserved = 0;
unixFile *pFile = (unixFile*)id;
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
*pResOut = reserved;
return rc;
if( pFile->eFileLock>=SHARED_LOCK ){
*pResOut = 0;
}else{
*pResOut = osAccess((const char*)pFile->lockingContext, 0)==0;
}
OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut));
return SQLITE_OK;
}
/*

View File

@ -11,10 +11,10 @@
# This file implements regression tests for SQLite library. The
# focus of this script is database locks.
#
# $Id: lock5.test,v 1.6 2008/12/04 12:34:16 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix lock5
# This file is only run if using the unix backend compiled with the
# SQLITE_ENABLE_LOCKING_STYLE macro.
@ -101,10 +101,7 @@ do_test lock5-dotfile.X {
#####################################################################
forcedelete test.db
if {[catch {sqlite3 db test.db -vfs unix-flock} msg]} {
finish_test
return
}
if {0==[catch {sqlite3 db test.db -vfs unix-flock} msg]} {
do_test lock5-flock.1 {
sqlite3 db test.db -vfs unix-flock
@ -149,13 +146,19 @@ do_test lock5-flock.8 {
db2 close
} {}
}
#####################################################################
reset_db
do_test lock5-none.1 {
sqlite3 db test.db -vfs unix-none
sqlite3 db2 test.db -vfs unix-none
execsql { PRAGMA mmap_size = 0 } db2
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
BEGIN;
INSERT INTO t1 VALUES(3, 4);
}
@ -178,10 +181,12 @@ do_test lock5-none.5 {
} {1 2}
ifcapable memorymanage {
do_test lock5-none.6 {
sqlite3_release_memory 1000000
execsql {SELECT * FROM t1} db2
} {1 2 3 4}
if {[permutation]!="memsubsys1" && [permutation]!="memsubsys2"} {
do_test lock5-none.6 {
sqlite3_release_memory 1000000
execsql {SELECT * FROM t1} db2
} {1 2 3 4}
}
}
do_test lock5-none.X {
@ -193,4 +198,76 @@ ifcapable lock_proxy_pragmas {
set env(SQLITE_FORCE_PROXY_LOCKING) $::using_proxy
}
#####################################################################
reset_db
if {[permutation]!="inmemory_journal"} {
# 1. Create a large database using the unix-dotfile VFS
# 2. Write a large transaction to the db, so that the cache spills, but do
# not commit it.
# 3. Make a copy of the database files on disk.
# 4. Try to read from the copy using unix-dotfile VFS. This fails because
# the dotfile still exists, so SQLite things the database is locked.
# 5. Remove the dotfile.
# 6. Try to read the db again. This time, the old transaction is rolled
# back and the read permitted.
#
do_test 2.dotfile.1 {
sqlite3 db test.db -vfs unix-dotfile
execsql {
PRAGMA cache_size = 10;
CREATE TABLE t1(x, y, z);
CREATE INDEX t1x ON t1(x);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000
)
INSERT INTO t1 SELECT hex(randomblob(20)), hex(randomblob(500)), i FROM s;
}
} {}
do_execsql_test 2.dotfile.2 {
BEGIN;
UPDATE t1 SET z=z+1, x=hex(randomblob(20));
}
do_test 2.dotfile.3 {
list \
[file exists test.db] \
[file exists test.db-journal] \
[file exists test.db.lock]
} {1 1 1}
do_test 2.dotfile.4 {
forcecopy test.db test.db2
forcecopy test.db-journal test.db2-journal
file mkdir test.db2.lock
sqlite3 db2 test.db2 -vfs unix-dotfile
catchsql {
SELECT count(*) FROM t1;
} db2
} {1 {database is locked}}
do_test 2.dotfile.5 {
file delete test.db2.lock
execsql {
PRAGMA integrity_check
} db2
} {ok}
db2 close
do_test 2.dotfile.6 {
forcecopy test.db test.db2
forcecopy test.db-journal test.db2-journal
sqlite3 db2 file:test.db2?nolock=1 -vfs unix-dotfile -uri 1
catchsql {
SELECT count(*) FROM t1;
} db2
} {0 1000}
}
finish_test