walbak.test 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. # 2010 April 22
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library. The
  12. # focus of this file is testing the operation of the library in
  13. # "PRAGMA journal_mode=WAL" mode.
  14. #
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. source $testdir/wal_common.tcl
  18. source $testdir/malloc_common.tcl
  19. do_not_use_codec
  20. ifcapable !wal {finish_test ; return }
  21. # Test organization:
  22. #
  23. # walback-1.*: Simple tests.
  24. #
  25. # walback-2.*: Test backups when the source db is modified mid-backup.
  26. #
  27. # walback-3.*: Backup of WAL sources into rollback destinations, and
  28. # vice-versa.
  29. #
  30. # Make sure a simple backup from a WAL database works.
  31. #
  32. do_test walbak-1.0 {
  33. execsql {
  34. PRAGMA synchronous = NORMAL;
  35. PRAGMA page_size = 1024;
  36. PRAGMA auto_vacuum = 0;
  37. PRAGMA journal_mode = wal;
  38. BEGIN;
  39. CREATE TABLE t1(a PRIMARY KEY, b);
  40. INSERT INTO t1 VALUES('I', 'one');
  41. COMMIT;
  42. }
  43. } {wal}
  44. do_test walbak-1.1 {
  45. forcedelete bak.db bak.db-journal bak.db-wal
  46. db backup bak.db
  47. file size bak.db
  48. } [expr 3*1024]
  49. do_test walbak-1.2 {
  50. sqlite3 db2 bak.db
  51. execsql {
  52. SELECT * FROM t1;
  53. PRAGMA main.journal_mode;
  54. } db2
  55. } {I one wal}
  56. do_test walbak-1.3 {
  57. execsql { PRAGMA integrity_check } db2
  58. } {ok}
  59. db2 close
  60. # Try a VACUUM on a WAL database.
  61. #
  62. do_test walbak-1.4 {
  63. execsql {
  64. VACUUM;
  65. PRAGMA main.journal_mode;
  66. }
  67. } {wal}
  68. do_test walbak-1.5 {
  69. list [file size test.db] [file size test.db-wal]
  70. } [list 1024 [wal_file_size 6 1024]]
  71. do_test walbak-1.6 {
  72. execsql { PRAGMA wal_checkpoint }
  73. list [file size test.db] [file size test.db-wal]
  74. } [list [expr 3*1024] [wal_file_size 6 1024]]
  75. do_test walbak-1.6.1 {
  76. hexio_read test.db 18 2
  77. } {0202}
  78. do_test walbak-1.7 {
  79. execsql {
  80. CREATE TABLE t2(a, b);
  81. INSERT INTO t2 SELECT * FROM t1;
  82. DROP TABLE t1;
  83. }
  84. list [file size test.db] [file size test.db-wal]
  85. } [list [expr 3*1024] [wal_file_size 6 1024]]
  86. do_test walbak-1.8 {
  87. execsql { VACUUM }
  88. list [file size test.db] [file size test.db-wal]
  89. } [list [expr 3*1024] [wal_file_size 8 1024]]
  90. do_test walbak-1.9 {
  91. execsql { PRAGMA wal_checkpoint }
  92. list [file size test.db] [file size test.db-wal]
  93. } [list [expr 2*1024] [wal_file_size 8 1024]]
  94. #-------------------------------------------------------------------------
  95. # Backups when the source db is modified mid-backup.
  96. #
  97. proc sig {{db db}} {
  98. $db eval {
  99. PRAGMA integrity_check;
  100. SELECT md5sum(a, b) FROM t1;
  101. }
  102. }
  103. db close
  104. delete_file test.db
  105. sqlite3 db test.db
  106. do_test walbak-2.1 {
  107. execsql { PRAGMA journal_mode = WAL }
  108. execsql {
  109. CREATE TABLE t1(a PRIMARY KEY, b);
  110. BEGIN;
  111. INSERT INTO t1 VALUES(randomblob(500), randomblob(500));
  112. INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM t1; /* 2 */
  113. INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM t1; /* 4 */
  114. INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM t1; /* 8 */
  115. INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM t1; /* 16 */
  116. INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM t1; /* 32 */
  117. INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM t1; /* 64 */
  118. COMMIT;
  119. }
  120. } {}
  121. do_test walbak-2.2 {
  122. db backup abc.db
  123. sqlite3 db2 abc.db
  124. string compare [sig db] [sig db2]
  125. } {0}
  126. do_test walbak-2.3 {
  127. sqlite3_backup B db2 main db main
  128. B step 50
  129. execsql { UPDATE t1 SET b = randomblob(500) }
  130. list [B step 1000] [B finish]
  131. } {SQLITE_DONE SQLITE_OK}
  132. do_test walbak-2.4 {
  133. string compare [sig db] [sig db2]
  134. } {0}
  135. do_test walbak-2.5 {
  136. db close
  137. sqlite3 db test.db
  138. execsql { PRAGMA cache_size = 10 }
  139. sqlite3_backup B db2 main db main
  140. B step 50
  141. execsql {
  142. BEGIN;
  143. UPDATE t1 SET b = randomblob(500);
  144. }
  145. expr [file size test.db-wal] > 10*1024
  146. } {1}
  147. do_test walbak-2.6 {
  148. B step 1000
  149. } {SQLITE_BUSY}
  150. do_test walbak-2.7 {
  151. execsql COMMIT
  152. list [B step 1000] [B finish]
  153. } {SQLITE_DONE SQLITE_OK}
  154. do_test walbak-2.8 {
  155. string compare [sig db] [sig db2]
  156. } {0}
  157. do_test walbak-2.9 {
  158. db close
  159. sqlite3 db test.db
  160. execsql { PRAGMA cache_size = 10 }
  161. sqlite3_backup B db2 main db main
  162. B step 50
  163. execsql {
  164. BEGIN;
  165. UPDATE t1 SET b = randomblob(500);
  166. }
  167. expr [file size test.db-wal] > 10*1024
  168. } {1}
  169. do_test walbak-2.10 {
  170. B step 1000
  171. } {SQLITE_BUSY}
  172. do_test walbak-2.11 {
  173. execsql ROLLBACK
  174. set sigB [sig db]
  175. list [B step 1000] [B finish]
  176. } {SQLITE_DONE SQLITE_OK}
  177. do_test walbak-2.12 {
  178. string compare [sig db] [sig db2]
  179. } {0}
  180. db2 close
  181. db close
  182. #-------------------------------------------------------------------------
  183. # Run some backup operations to copy back and forth between WAL and:
  184. #
  185. # walbak-3.1.*: an in-memory database
  186. #
  187. # walbak-3.2.*: a temporary database
  188. #
  189. # walbak-3.3.*: a database in rollback mode.
  190. #
  191. # walbak-3.4.*: a database in rollback mode that (initially) uses a
  192. # different page-size.
  193. #
  194. # Check that this does not confuse any connected clients.
  195. #
  196. foreach {tn setup} {
  197. 1 {
  198. sqlite3 db test.db
  199. sqlite3 db2 :memory:
  200. db eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
  201. db2 eval { PRAGMA page_size = 1024 }
  202. }
  203. 2 {
  204. sqlite3 db test.db
  205. sqlite3 db2 ""
  206. db eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
  207. db2 eval { PRAGMA page_size = 1024 }
  208. }
  209. 3 {
  210. sqlite3 db test.db
  211. sqlite3 db2 test.db2
  212. db eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
  213. db2 eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = PERSIST }
  214. }
  215. 4 {
  216. sqlite3 db test.db
  217. sqlite3 db2 test.db2
  218. db eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
  219. db2 eval {
  220. PRAGMA page_size = 2048;
  221. PRAGMA journal_mode = PERSIST;
  222. CREATE TABLE xx(x);
  223. }
  224. }
  225. } {
  226. foreach f [glob -nocomplain test.db*] { forcedelete $f }
  227. eval $setup
  228. do_test walbak-3.$tn.1 {
  229. execsql {
  230. CREATE TABLE t1(a, b);
  231. INSERT INTO t1 VALUES(1, 2);
  232. INSERT INTO t1 VALUES(3, 4);
  233. SELECT * FROM t1;
  234. }
  235. } {1 2 3 4}
  236. do_test walbak-3.$tn.2 {
  237. sqlite3_backup B db2 main db main
  238. B step 10000
  239. B finish
  240. execsql { SELECT * FROM t1 } db2
  241. } {1 2 3 4}
  242. do_test walbak-3.$tn.3 {
  243. execsql {
  244. INSERT INTO t1 VALUES(5, 6);
  245. INSERT INTO t1 VALUES(7, 8);
  246. SELECT * FROM t1;
  247. } db2
  248. } {1 2 3 4 5 6 7 8}
  249. do_test walbak-3.$tn.4 {
  250. sqlite3_backup B db main db2 main
  251. B step 10000
  252. B finish
  253. execsql { SELECT * FROM t1 }
  254. } {1 2 3 4 5 6 7 8}
  255. # Check that [db] is still in WAL mode.
  256. do_test walbak-3.$tn.5 {
  257. execsql { PRAGMA journal_mode }
  258. } {wal}
  259. do_test walbak-3.$tn.6 {
  260. execsql { PRAGMA wal_checkpoint }
  261. hexio_read test.db 18 2
  262. } {0202}
  263. # If it was not an in-memory database, check that [db2] is still in
  264. # rollback mode.
  265. if {[file exists test.db2]} {
  266. do_test walbak-3.$tn.7 {
  267. execsql { PRAGMA journal_mode } db2
  268. } {wal}
  269. do_test walbak-3.$tn.8 {
  270. execsql { PRAGMA wal_checkpoint }
  271. hexio_read test.db 18 2
  272. } {0202}
  273. }
  274. db close
  275. db2 close
  276. }
  277. #-------------------------------------------------------------------------
  278. # Test that the following holds when a backup operation is run:
  279. #
  280. # Source | Destination inital | Destination final
  281. # ---------------------------------------------------
  282. # Rollback Rollback Rollback
  283. # Rollback WAL WAL
  284. # WAL Rollback WAL
  285. # WAL WAL WAL
  286. #
  287. foreach {tn src dest dest_final} {
  288. 1 delete delete delete
  289. 2 delete wal wal
  290. 3 wal delete wal
  291. 4 wal wal wal
  292. } {
  293. catch { db close }
  294. catch { db2 close }
  295. forcedelete test.db test.db2
  296. do_test walbak-4.$tn.1 {
  297. sqlite3 db test.db
  298. db eval "PRAGMA journal_mode = $src"
  299. db eval {
  300. CREATE TABLE t1(a, b);
  301. INSERT INTO t1 VALUES('I', 'II');
  302. INSERT INTO t1 VALUES('III', 'IV');
  303. }
  304. sqlite3 db2 test.db2
  305. db2 eval "PRAGMA journal_mode = $dest"
  306. db2 eval {
  307. CREATE TABLE t2(x, y);
  308. INSERT INTO t2 VALUES('1', '2');
  309. INSERT INTO t2 VALUES('3', '4');
  310. }
  311. } {}
  312. do_test walbak-4.$tn.2 { execsql { PRAGMA journal_mode } db } $src
  313. do_test walbak-4.$tn.3 { execsql { PRAGMA journal_mode } db2 } $dest
  314. do_test walbak-4.$tn.4 { db backup test.db2 } {}
  315. do_test walbak-4.$tn.5 {
  316. execsql { SELECT * FROM t1 } db2
  317. } {I II III IV}
  318. do_test walbak-4.$tn.5 { execsql { PRAGMA journal_mode } db2 } $dest_final
  319. db2 close
  320. do_test walbak-4.$tn.6 { file exists test.db2-wal } 0
  321. sqlite3 db2 test.db2
  322. do_test walbak-4.$tn.7 { execsql { PRAGMA journal_mode } db2 } $dest_final
  323. }
  324. finish_test