incrvacuum2.test 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # 2007 May 04
  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 incremental vacuum feature.
  13. #
  14. # $Id: incrvacuum2.test,v 1.6 2009/07/25 13:42:50 danielk1977 Exp $
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. # If this build of the library does not support auto-vacuum, omit this
  18. # whole file.
  19. ifcapable {!autovacuum || !pragma} {
  20. finish_test
  21. return
  22. }
  23. set testprefix incrvacuum2
  24. # Create a database in incremental vacuum mode that has many
  25. # pages on the freelist.
  26. #
  27. do_test incrvacuum2-1.1 {
  28. execsql {
  29. PRAGMA page_size=1024;
  30. PRAGMA auto_vacuum=incremental;
  31. CREATE TABLE t1(x);
  32. INSERT INTO t1 VALUES(zeroblob(30000));
  33. DELETE FROM t1;
  34. }
  35. file size test.db
  36. } {32768}
  37. # Vacuum off a single page.
  38. #
  39. do_test incrvacuum2-1.2 {
  40. execsql {
  41. PRAGMA incremental_vacuum(1);
  42. }
  43. file size test.db
  44. } {31744}
  45. # Vacuum off five pages
  46. #
  47. do_test incrvacuum2-1.3 {
  48. execsql {
  49. PRAGMA incremental_vacuum(5);
  50. }
  51. file size test.db
  52. } {26624}
  53. # Vacuum off all the rest
  54. #
  55. do_test incrvacuum2-1.4 {
  56. execsql {
  57. PRAGMA incremental_vacuum(1000);
  58. }
  59. file size test.db
  60. } {3072}
  61. # Make sure incremental vacuum works on attached databases.
  62. #
  63. ifcapable attach {
  64. do_test incrvacuum2-2.1 {
  65. forcedelete test2.db test2.db-journal
  66. execsql {
  67. ATTACH DATABASE 'test2.db' AS aux;
  68. PRAGMA aux.auto_vacuum=incremental;
  69. CREATE TABLE aux.t2(x);
  70. INSERT INTO t2 VALUES(zeroblob(30000));
  71. INSERT INTO t1 SELECT * FROM t2;
  72. DELETE FROM t2;
  73. DELETE FROM t1;
  74. }
  75. list [file size test.db] [file size test2.db]
  76. } {32768 32768}
  77. do_test incrvacuum2-2.2 {
  78. execsql {
  79. PRAGMA aux.incremental_vacuum(1)
  80. }
  81. list [file size test.db] [file size test2.db]
  82. } {32768 31744}
  83. do_test incrvacuum2-2.3 {
  84. execsql {
  85. PRAGMA aux.incremental_vacuum(5)
  86. }
  87. list [file size test.db] [file size test2.db]
  88. } {32768 26624}
  89. do_test incrvacuum2-2.4 {
  90. execsql {
  91. PRAGMA main.incremental_vacuum(5)
  92. }
  93. list [file size test.db] [file size test2.db]
  94. } {27648 26624}
  95. do_test incrvacuum2-2.5 {
  96. execsql {
  97. PRAGMA aux.incremental_vacuum
  98. }
  99. list [file size test.db] [file size test2.db]
  100. } {27648 3072}
  101. do_test incrvacuum2-2.6 {
  102. execsql {
  103. PRAGMA incremental_vacuum(1)
  104. }
  105. list [file size test.db] [file size test2.db]
  106. } {26624 3072}
  107. }
  108. do_test incrvacuum2-3.1 {
  109. execsql {
  110. PRAGMA auto_vacuum = 'full';
  111. BEGIN;
  112. CREATE TABLE abc(a);
  113. INSERT INTO abc VALUES(randstr(1500,1500));
  114. COMMIT;
  115. }
  116. } {}
  117. do_test incrvacuum2-3.2 {
  118. execsql {
  119. BEGIN;
  120. DELETE FROM abc;
  121. PRAGMA incremental_vacuum;
  122. COMMIT;
  123. }
  124. } {}
  125. integrity_check incrvacuum2-3.3
  126. ifcapable wal {
  127. # At one point, when a specific page was being extracted from the b-tree
  128. # free-list (e.g. during an incremental-vacuum), all trunk pages that
  129. # occurred before the specific page in the free-list trunk were being
  130. # written to the journal or wal file. This is not necessary. Only the
  131. # extracted page and the page that contains the pointer to it need to
  132. # be journalled.
  133. #
  134. # This problem was fixed by [d03d63d77e] (just before 3.7.6 release).
  135. #
  136. # This test case builds a database containing many free pages. Then runs
  137. # "PRAGMA incremental_vacuum(1)" until the db contains zero free pages.
  138. # Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The
  139. # worst case is when a trunk page is removed from the end of the db file.
  140. # In this case pages written are:
  141. #
  142. # 1. The previous trunk page (that contains a pointer to the recycled
  143. # trunk page), and
  144. # 2. The leaf page transformed into a trunk page to replace the recycled
  145. # page, and
  146. # 3. The trunk page that contained a pointer to the leaf page used
  147. # in (2), and
  148. # 4. Page 1. Page 1 is always updated, even in WAL mode, since it contains
  149. # the "number of free-list pages" field.
  150. #
  151. db close
  152. forcedelete test.db
  153. sqlite3 db test.db
  154. do_execsql_test 4.1 {
  155. PRAGMA page_size = 512;
  156. PRAGMA auto_vacuum = 2;
  157. CREATE TABLE t1(x);
  158. INSERT INTO t1 VALUES(randomblob(400));
  159. INSERT INTO t1 SELECT * FROM t1; -- 2
  160. INSERT INTO t1 SELECT * FROM t1; -- 4
  161. INSERT INTO t1 SELECT * FROM t1; -- 8
  162. INSERT INTO t1 SELECT * FROM t1; -- 16
  163. INSERT INTO t1 SELECT * FROM t1; -- 32
  164. INSERT INTO t1 SELECT * FROM t1; -- 128
  165. INSERT INTO t1 SELECT * FROM t1; -- 256
  166. INSERT INTO t1 SELECT * FROM t1; -- 512
  167. INSERT INTO t1 SELECT * FROM t1; -- 1024
  168. INSERT INTO t1 SELECT * FROM t1; -- 2048
  169. INSERT INTO t1 SELECT * FROM t1; -- 4096
  170. INSERT INTO t1 SELECT * FROM t1; -- 8192
  171. DELETE FROM t1 WHERE oid>512;
  172. DELETE FROM t1;
  173. }
  174. do_test 4.2 {
  175. execsql {
  176. PRAGMA journal_mode = WAL;
  177. PRAGMA incremental_vacuum(1);
  178. PRAGMA wal_checkpoint;
  179. }
  180. file size test.db-wal
  181. } [expr {32+2*(512+24)}]
  182. do_test 4.3 {
  183. db close
  184. sqlite3 db test.db
  185. set maxsz 0
  186. while {[file size test.db] > [expr 512*3]} {
  187. execsql { PRAGMA journal_mode = WAL }
  188. execsql { PRAGMA wal_checkpoint }
  189. execsql { PRAGMA incremental_vacuum(1) }
  190. set newsz [file size test.db-wal]
  191. if {$newsz>$maxsz} {set maxsz $newsz}
  192. }
  193. set maxsz
  194. } [expr {32+3*(512+24)}]
  195. }
  196. finish_test