Index: third_party/sqlite/src/test/incrvacuum2.test |
diff --git a/third_party/sqlite/src/test/incrvacuum2.test b/third_party/sqlite/src/test/incrvacuum2.test |
index d8a391b7136ae435adc9988d7ede7da50b6e1baf..902517c9494e13570ff8bae7827ca0706f5e81d2 100644 |
--- a/third_party/sqlite/src/test/incrvacuum2.test |
+++ b/third_party/sqlite/src/test/incrvacuum2.test |
@@ -23,6 +23,7 @@ ifcapable {!autovacuum || !pragma} { |
return |
} |
+set testprefix incrvacuum2 |
# Create a database in incremental vacuum mode that has many |
# pages on the freelist. |
@@ -131,6 +132,80 @@ do_test incrvacuum2-3.2 { |
} |
} {} |
-integrity_check incremental2-3.3 |
+integrity_check incrvacuum2-3.3 |
+ |
+ifcapable wal { |
+ # At one point, when a specific page was being extracted from the b-tree |
+ # free-list (e.g. during an incremental-vacuum), all trunk pages that |
+ # occurred before the specific page in the free-list trunk were being |
+ # written to the journal or wal file. This is not necessary. Only the |
+ # extracted page and the page that contains the pointer to it need to |
+ # be journalled. |
+ # |
+ # This problem was fixed by [d03d63d77e] (just before 3.7.6 release). |
+ # |
+ # This test case builds a database containing many free pages. Then runs |
+ # "PRAGMA incremental_vacuum(1)" until the db contains zero free pages. |
+ # Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The |
+ # worst case is when a trunk page is removed from the end of the db file. |
+ # In this case pages written are: |
+ # |
+ # 1. The previous trunk page (that contains a pointer to the recycled |
+ # trunk page), and |
+ # 2. The leaf page transformed into a trunk page to replace the recycled |
+ # page, and |
+ # 3. The trunk page that contained a pointer to the leaf page used |
+ # in (2), and |
+ # 4. Page 1. Page 1 is always updated, even in WAL mode, since it contains |
+ # the "number of free-list pages" field. |
+ # |
+ db close |
+ forcedelete test.db |
+ sqlite3 db test.db |
+ |
+ do_execsql_test 4.1 { |
+ PRAGMA page_size = 512; |
+ PRAGMA auto_vacuum = 2; |
+ CREATE TABLE t1(x); |
+ INSERT INTO t1 VALUES(randomblob(400)); |
+ INSERT INTO t1 SELECT * FROM t1; -- 2 |
+ INSERT INTO t1 SELECT * FROM t1; -- 4 |
+ INSERT INTO t1 SELECT * FROM t1; -- 8 |
+ INSERT INTO t1 SELECT * FROM t1; -- 16 |
+ INSERT INTO t1 SELECT * FROM t1; -- 32 |
+ INSERT INTO t1 SELECT * FROM t1; -- 128 |
+ INSERT INTO t1 SELECT * FROM t1; -- 256 |
+ INSERT INTO t1 SELECT * FROM t1; -- 512 |
+ INSERT INTO t1 SELECT * FROM t1; -- 1024 |
+ INSERT INTO t1 SELECT * FROM t1; -- 2048 |
+ INSERT INTO t1 SELECT * FROM t1; -- 4096 |
+ INSERT INTO t1 SELECT * FROM t1; -- 8192 |
+ DELETE FROM t1 WHERE oid>512; |
+ DELETE FROM t1; |
+ } |
+ |
+ do_test 4.2 { |
+ execsql { |
+ PRAGMA journal_mode = WAL; |
+ PRAGMA incremental_vacuum(1); |
+ PRAGMA wal_checkpoint; |
+ } |
+ file size test.db-wal |
+ } {1640} |
+ |
+ do_test 4.3 { |
+ db close |
+ sqlite3 db test.db |
+ set maxsz 0 |
+ while {[file size test.db] > [expr 512*3]} { |
+ execsql { PRAGMA journal_mode = WAL } |
+ execsql { PRAGMA wal_checkpoint } |
+ execsql { PRAGMA incremental_vacuum(1) } |
+ set newsz [file size test.db-wal] |
+ if {$newsz>$maxsz} {set maxsz $newsz} |
+ } |
+ set maxsz |
+ } {2176} |
+} |
finish_test |