# 2012 May 30
#
# 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.
#
#***********************************************************************
# The tests in this file focus on testing test that the LSM log file is
# written and recovered correctly.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/log_common.tcl
set testprefix log2
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
}
do_recover_test 1.1 {
PRAGMA integrity_check;
SELECT * FROM t1;
} { ok 1 2 3 4}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a PRIMARY KEY, b);
CREATE INDEX i1 ON t1(b, a);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
}
do_recover_test 2.1 { SELECT * FROM t1 } {1 2 3 4}
do_execsql_test 2.2 {
BEGIN;
INSERT INTO t1 VALUES(7, 8);
ROLLBACK;
BEGIN;
INSERT INTO t1 VALUES(5, 6);
COMMIT;
}
do_filesize_test 2.3 0 241
do_recover_test 2.4 { SELECT * FROM t1 } {1 2 3 4 5 6}
do_execsql_test 2.5 {
BEGIN;
SAVEPOINT one;
INSERT INTO t1 VALUES(9, 10);
ROLLBACK TO one;
INSERT INTO t1 VALUES(7, 8);
COMMIT;
}
do_filesize_test 2.6 0 271
do_execsql_test 2.7.1 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8}
do_recover_test 2.7.2 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8}
#-------------------------------------------------------------------------
#
reset_db
do_test 3.1 { sqlite4_lsm_config db main log-size 800 } 800
do_execsql_test 3.2 {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(randstr(10,10), randstr(1000,1000));
}
do_test 3.3 { sqlite4_lsm_work db main -flush } {0}
do_execsql_test 3.4 {
INSERT INTO t1 VALUES(randstr(10,10), randstr(100,100));
}
do_test 3.5 { sqlite4_lsm_work db main -check } {0}
do_execsql_test 3.6 { INSERT INTO t1 VALUES(randstr(10,10), randstr(100,100)) }
do_test 3.7 {
sqlite4_lsm_info db main log-structure
} {1124 1271 0 0 0 139}
do_test 3.8 { sqlite4_lsm_work db main -flush } {0}
do_execsql_test 3.9 { INSERT INTO t1 VALUES(randstr(10,10), randstr(100,100)) }
do_test 3.10 {
execsql BEGIN
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
sqlite4 db2 ./test.db
sqlite4_lsm_work db2 main -check
db2 close
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql { INSERT INTO t1 VALUES(randstr(10,10), randstr(100, 100)) }
execsql COMMIT
} {}
do_test 3.11 {
sqlite4_lsm_info db main log-structure
} {0 0 139 1062 1272 1809}
do_recover_test 3.12 { SELECT * FROM t1 } [execsql {SELECT * FROM t1}]
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.1 {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(randstr(10,10), randstr(1000,1000));
BEGIN;
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 2
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 4
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 8
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 16
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 32
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 64
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 128
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 256
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 512
INSERT INTO t1 SELECT randstr(10,10), randstr(1000,1000) FROM t1; -- 1024
COMMIT
}
do_recover_test 4.2 { SELECT count(*) FROM t1 } 1024
#-------------------------------------------------------------------------
# The point of this test case is to try to trick LSM into making a large
# allocation internally as the result of a corrupt log file.
#
reset_db
do_execsql_test 5.1 {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(randstr(10,10), randstr(1000,1000));
}
do_test 5.2 { sqlite4_lsm_info db main log-structure } {0 0 0 0 0 1124}
do_test 5.3 {
copy_db_files test.db test.db2
# A WRITE (0x06) record specifying an 8 (varint 08) byte key and
# 2,000,000,000 (varint FB77359400) byte value. And a few bytes of garbage
# following.
hexio_write test.db2-log 1124 0608FB77359400
hexio_write test.db2-log 1130 5555555555555555555555555555
sqlite4 db2 ./test.db2
execsql { SELECT count(*) FROM t1 } db2
} {1}
#-------------------------------------------------------------------------
#
reset_db
set a [string repeat A 50000]
set b [string repeat B 50000]
set c [string repeat C 50000]
set d [string repeat D 50000]
do_execsql_test 6.1 {
CREATE TABLE t1(a, b, PRIMARY KEY(a, b));
INSERT INTO t1 VALUES($a, $b);
INSERT INTO t1 VALUES($b, $c);
INSERT INTO t1 VALUES($c, $d);
INSERT INTO t1 VALUES($d, $a);
} {}
do_test 6.2 {
set cksum [db one { SELECT md5sum(a, b) FROM t1 }]
execsql { PRAGMA integrity_check }
} {ok}
do_test 6.3 { file size test.db } 0
do_recover_test 6.4 {
SELECT md5sum(a, b) FROM t1;
} [list $cksum]
finish_test