Test that a race condition can cause a "BEGIN EXCLUSIVE" to return

SQLITE_BUSY_SNAPSHOT in wal mode.

FossilOrigin-Name: 5a12db75d1da65daa92413a6b5892309e9d9479bb3610764e1015abe5bf28dbe
This commit is contained in:
dan
2018-07-03 20:17:27 +00:00
parent d736829e8b
commit 7fee0bfad2
3 changed files with 104 additions and 6 deletions
+6 -5
View File
@@ -1,5 +1,5 @@
C Fix\sa\sproblem\sin\sthe\sxInverse\scallback\sfor\sthe\sbuilt-in\ssum()\swindow\sfunction.
D 2018-07-02T17:45:59.790
C Test\sthat\sa\srace\scondition\scan\scause\sa\s"BEGIN\sEXCLUSIVE"\sto\sreturn\nSQLITE_BUSY_SNAPSHOT\sin\swal\smode.
D 2018-07-03T20:17:27.649
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -1583,6 +1583,7 @@ F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walprotocol.test a112aba0b79e3adeaa485fed09484b32c654e97df58e454aa8489ac2cd57bf84
F test/walprotocol2.test ad92f036102f722b2d7f7ca7c1faf72d75f501a50c80a92d7fd87f8b1da6608c
F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
F test/walro2.test 0e79dd15cbdb4f482c01ea248373669c732414a726b357d04846a816afafb768
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
@@ -1744,7 +1745,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 693b4350d741391226a33ab6a05eaad61e8ef1590176f01e8aed2a212e2d6419
R 2a905c5056bd462d63ab558902828293
P b6563647382634588ebe5c6a3c35c65a321dc1b3732c809d48ce46759b9dd80f
R 85d71bbec8ad4dcf2f8e9507c907b291
U dan
Z e86ae3bb9d5c5564eb7cd669366300ff
Z 38cb85199c9d8fc14bf46fba2bfb3f49
+1 -1
View File
@@ -1 +1 @@
b6563647382634588ebe5c6a3c35c65a321dc1b3732c809d48ce46759b9dd80f
5a12db75d1da65daa92413a6b5892309e9d9479bb3610764e1015abe5bf28dbe
+97
View File
@@ -0,0 +1,97 @@
# 2018 July 4
#
# 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/lock_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
set testprefix walprotocol2
#-------------------------------------------------------------------------
# When recovering the contents of a WAL file, a process obtains the WRITER
# lock, then locks all other bytes before commencing recovery. If it fails
# to lock all other bytes (because some other process is holding a read
# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the
# caller. Test this (test case 1.3).
#
# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain
# the WRITER lock (should be the same). Test case 1.4.
#
do_execsql_test 1.0 {
PRAGMA journal_mode = wal;
CREATE TABLE x(y);
INSERT INTO x VALUES('z');
} {wal}
db close
proc lock_callback {method filename handle lock} {
# puts "$method $filename $handle $lock"
}
testvfs T
T filter xShmLock
T script lock_callback
sqlite3 db test.db -vfs T
sqlite3 db2 test.db -vfs T
do_execsql_test 2.0 {
SELECT * FROM x;
} {z}
do_execsql_test -db db2 2.1 {
SELECT * FROM x;
} {z}
#---------------------------------------------------------------
# Attempt a "BEGIN EXCLUSIVE" using connection handle [db]. This
# causes SQLite to open a read transaction, then a write transaction.
# Rig the xShmLock() callback so that just before the EXCLUSIVE lock
# for the write transaction is taken, connection [db2] jumps in and
# modifies the database. This causes the "BEGIN EXCLUSIVE" to throw
# an SQLITE_BUSY_SNAPSHOT error.
#
proc lock_callback {method filename handle lock} {
if {$lock=="0 1 lock exclusive"} {
proc lock_callback {method filename handle lock} {}
db2 eval { INSERT INTO x VALUES('y') }
}
}
do_catchsql_test 2.2 {
BEGIN EXCLUSIVE;
} {1 {database is locked}}
do_test 2.3 {
sqlite3_extended_errcode db
} {SQLITE_BUSY_SNAPSHOT}
#---------------------------------------------------------------
# Same again, but with a busy-handler. This time, following the
# SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the
# whole thing retried from the beginning. This time it succeeds.
#
proc lock_callback {method filename handle lock} {
if {$lock=="0 1 lock exclusive"} {
proc lock_callback {method filename handle lock} {}
db2 eval { INSERT INTO x VALUES('x') }
}
}
db timeout 10
do_catchsql_test 2.4 {
BEGIN EXCLUSIVE;
} {0 {}}
do_execsql_test 2.5 {
SELECT * FROM x;
COMMIT;
} {z y x}
finish_test