]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add test case demonstrating deadlock during recovery of very large log files. No...
authordan <dan@noemail.net>
Sat, 1 May 2010 08:30:34 +0000 (08:30 +0000)
committerdan <dan@noemail.net>
Sat, 1 May 2010 08:30:34 +0000 (08:30 +0000)
FossilOrigin-Name: 63ea318eb19d264667909c70185b8a5cdc4454c0

manifest
manifest.uuid
test/walthread.test

index 15a349d662411ee82d233963246c030190b5cfd7..fca9dd688fbc7211c8effc91f43fc04190673b08 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Do\snot\sallow\sjournal_mode=WAL\sif\sthe\sunderlying\sVFS\sdoes\snot\ssupport\sxShmOpen.
-D 2010-05-01T00:59:38
+C Add\stest\scase\sdemonstrating\sdeadlock\sduring\srecovery\sof\svery\slarge\slog\sfiles.\sNo\sfix\syet.
+D 2010-05-01T08:30:35
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -767,7 +764,7 @@ F test/walcrash.test f022cee7eb7baa5fb898726120a6a4073dd831d1
 F test/walhook.test 287a69d662939604f2e0452dace2cec8ef634d5e
 F test/walmode.test 999be0fbee266ed618de780a6dadfca662d0f763
 F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2
-F test/walthread.test c9c3b5d19eeb4968254d93f61a7ccd6e8b63f554
+F test/walthread.test 896b2377145e32fab024677d68f609df2f6e9bc6
 F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
 F test/where3.test aa44a9b29e8c9f3d7bb94a3bb3a95b31627d520d
@@ -811,14 +808,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 76bf0eee1fd4003a3f1c39922f8f059611d41dd0
-R 9dfde34976e5276ea286640fcc12ec63
-U drh
-Z 32ec43d929a1f569787f34775d6f160c
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD4DBQFL23z+oxKgR168RlERAhO3AJ90Nf9l23uNBBZGi//1U+RT1mFhmQCWLU5N
-/Vu6AuAN53A7nGU5H1J5Vg==
-=7uDR
------END PGP SIGNATURE-----
+P d1fcccecdc8e9ac5d0d022914e51c545f4e1b04f
+R 034d4495629d0958f2c325287d33624b
+U dan
+Z 43bb63963c222b2fa1b30185cbd547d7
index 2ccd280d279a039a151f8cd646c31c34c78b48d1..abff647efb198258ad0c691aba7364c2ba7fed99 100644 (file)
@@ -1 +1 @@
-d1fcccecdc8e9ac5d0d022914e51c545f4e1b04f
\ No newline at end of file
+63ea318eb19d264667909c70185b8a5cdc4454c0
\ No newline at end of file
index efd321df3b4da18f42f2dfba1c544ff2efab6dea..fa42af9c6a7249b3ea939221a223905633576550 100644 (file)
@@ -28,6 +28,7 @@ set seconds(walthread-1) 20
 set seconds(walthread-2) 20
 set seconds(walthread-3) 20
 set seconds(walthread-4) 20
+set seconds(walthread-5) 1
 
 # The parameter is the name of a variable in the callers context. The
 # variable may or may not exist when this command is invoked.
@@ -130,7 +131,7 @@ proc do_thread_test {args} {
 
   sqlite3 db test.db
   eval $P(init)
-  db close
+  catch { db close }
 
   foreach T $P(threads) {
     set name  [lindex $T 0]
@@ -454,5 +455,81 @@ do_thread_test2 walthread-4 -seconds $seconds(walthread-4) -init {
   set {} ok
 }
 
+
+# This test case attempts to provoke a deadlock condition that existed in
+# the unix VFS at one point. The problem occurred only while recovering a 
+# very large wal file (one that requires a wal-index larger than the 
+# initial default allocation of 64KB).
+#
+# When recovering a log file, mutexes are usually obtained and released
+# as follows:
+#
+#   xShmGet                         ENTER mutexBuf
+#   xShmLock(RECOVER)               ENTER mutexRecov
+#     <do recovery work>
+#   xShmLock(READ)                  LEAVE mutexRecov
+#   xShmRelease                     LEAVE mutexBuf         
+#
+# However, if the initial wal-index allocation needs to be enlarged during
+# the recovery process, the mutex operations become:
+#
+#   xShmGet                         ENTER mutexBuf
+#   xShmLock(RECOVER)               ENTER mutexRecov
+#     <do first part of recovery work>
+#     xShmRelease                   LEAVE mutexBuf
+#     xShmSize
+#     xShmGet                       ENTER mutexBuf
+#     <do second part of recovery work>
+#   xShmLock(READ)                  LEAVE mutexRecov
+#   xShmRelease                     LEAVE mutexBuf         
+#
+# If multiple threads attempt the above simultaneously, deadlock can occur.
+#
+do_thread_test walthread-5 -seconds $seconds(walthread-5) -init {
+
+  proc log_file_size {nFrame pgsz} {
+    expr {12 + ($pgsz+16)*$nFrame}
+  }
+
+  execsql {
+    PRAGMA page_size = 1024;
+    PRAGMA journal_mode = WAL;
+    CREATE TABLE t1(x);
+    BEGIN;
+      INSERT INTO t1 VALUES(randomblob(900));
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*     2 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*     4 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*     8 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*    16 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*    32 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*    64 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*   128 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*   256 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*   512 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  1024 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  2048 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  4096 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  8192 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /* 16384 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /* 32768 */
+      INSERT INTO t1 SELECT randomblob(900) FROM t1;      /* 65536 */
+    COMMIT;
+  }
+
+  file copy -force test.db-wal bak.db-wal
+  file copy -force test.db bak.db
+  db close
+
+  file copy -force bak.db-wal test.db-wal
+  file copy -force bak.db test.db
+
+  if {[file size test.db-wal] < [log_file_size [expr 64*1024] 1024]} {
+    error "Somehow failed to create a large log file"
+  }
+  puts "Database with large log file recovered. Now running clients..."
+} -thread T 5 {
+  db eval { SELECT count(*) FROM t1 }
+}
+
 finish_test