#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/
2969 Kevin Lewis 2009-01-20
Bug#40801 - Testcase to show that the new scavenger does not
garbageCollect key values that are needed for records not pruned.
added:
mysql-test/suite/falcon/r/falcon_bug_40801.result
mysql-test/suite/falcon/t/falcon_bug_40801.test
per-file messages:
mysql-test/suite/falcon/r/falcon_bug_40801.result
Bug#40801 - Testcase to show that the new scavenger does not
garbageCollect key values that are needed for records not pruned.
mysql-test/suite/falcon/t/falcon_bug_40801.test
Bug#40801 - Testcase to show that the new scavenger does not
garbageCollect key values that are needed for records not pruned.
=== added file 'mysql-test/suite/falcon/r/falcon_bug_40801.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_40801.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_40801.result 2009-01-21 05:15:42 +0000
@@ -0,0 +1,97 @@
+#---- Bug 40801 ----
+SET @@storage_engine = 'Falcon';
+# Initialization
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a varchar(1000));
+INSERT INTO t1 VALUES (repeat('-', 1000));
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+CREATE TABLE t2 (f1 CHAR(10) PRIMARY KEY);
+INSERT INTO t2 VALUES ('-');
+UPDATE t2 SET f1 = 'A';
+UPDATE t2 SET f1 = 'B';
+UPDATE t2 SET f1 = 'C';
+UPDATE t2 SET f1 = 'D';
+# Establish connection con1 (user=root)
+BEGIN;
+SELECT * FROM t2;
+f1
+D
+SELECT * FROM t2 WHERE f1 = 'D';
+f1
+D
+# Use default client to commit an update;
+# Change the field value to 'A'
+UPDATE t2 SET f1 = 'A';
+# Establish connection con2 (user=root)
+BEGIN;
+SELECT * FROM t2;
+f1
+A
+SELECT * FROM t2 WHERE f1 = 'A';
+f1
+A
+# Use default client to commit an update;
+# Change the field value back to 'B'
+# and then 'C' in a second savepoint, then commit.
+BEGIN;
+UPDATE t2 SET f1 = 'B';
+SAVEPOINT sp1;
+UPDATE t2 SET f1 = 'C';
+RELEASE SAVEPOINT sp1;
+COMMIT;
+# Establish connection con3 (user=root)
+BEGIN;
+SELECT * FROM t2;
+f1
+C
+SELECT * FROM t2 WHERE f1 = 'C';
+f1
+C
+# Use default client to update value back to '-'
+UPDATE t2 SET f1 = '-';
+SELECT * FROM t2;
+f1
+-
+SELECT * FROM t2 WHERE f1 = '-';
+f1
+-
+# There now two record versions with 'A' & 'C'
+# This update should cause a scavenge to prune old records.
+UPDATE t1 SET a = repeat('a',1000);
+SELECT * FROM t2;
+f1
+D
+SELECT * FROM t2 WHERE f1 = 'D';
+f1
+D
+COMMIT;
+SELECT * FROM t2;
+f1
+A
+SELECT * FROM t2 WHERE f1 = 'A';
+f1
+A
+COMMIT;
+SELECT * FROM t2;
+f1
+C
+SELECT * FROM t2 WHERE f1 = 'C';
+f1
+C
+COMMIT;
+COMMIT;
+COMMIT;
+COMMIT;
+DROP TABLE t1, t2;
=== added file 'mysql-test/suite/falcon/t/falcon_bug_40801.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_40801.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_40801.test 2009-01-21 05:15:42 +0000
@@ -0,0 +1,132 @@
+# Bug#40801 - Falcon garbage collection can erase valid key values
+# Note: This test creates a second file that is used just to start
+# a scavenge cycle in which records will get pruned.
+# This file is sized to force a scavenge cycle for pruning
+# using the current scavenger design and the default setting
+# for record cache size. This test will not cause a scavenge
+# with the old scavenger. See the bug for a script that
+# reproduces this with the old scavenger.
+
+--echo #---- Bug 40801 ----
+
+--source include/have_falcon.inc
+
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--echo # Initialization
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+# Create a table to control scavenge cycles.
+# The new scavenger will scavenge for every (250Mb / 50) = 5Mb of record data.
+
+CREATE TABLE t1 (a varchar(1000));
+INSERT INTO t1 VALUES (repeat('-', 1000));
+INSERT INTO t1 SELECT * FROM t1; # 2,000
+INSERT INTO t1 SELECT * FROM t1; # 4,000
+INSERT INTO t1 SELECT * FROM t1; # 8,000
+INSERT INTO t1 SELECT * FROM t1; # 16,000
+INSERT INTO t1 SELECT * FROM t1; # 32,000
+INSERT INTO t1 SELECT * FROM t1; # 64,000
+INSERT INTO t1 SELECT * FROM t1; # 128,000
+INSERT INTO t1 SELECT * FROM t1; # 256,000
+INSERT INTO t1 SELECT * FROM t1; # 512,000
+INSERT INTO t1 SELECT * FROM t1; # 1,024,000
+INSERT INTO t1 SELECT * FROM t1; # 2,048,000
+INSERT INTO t1 SELECT * FROM t1; # 4,096,000
+INSERT INTO t1 SELECT * FROM t1; # 8,192,000
+# That should have caused at least one scavenge
+
+# Create a second table for the test.
+CREATE TABLE t2 (f1 CHAR(10) PRIMARY KEY);
+INSERT INTO t2 VALUES ('-');
+UPDATE t2 SET f1 = 'A';
+UPDATE t2 SET f1 = 'B';
+UPDATE t2 SET f1 = 'C';
+UPDATE t2 SET f1 = 'D';
+
+--echo # Establish connection con1 (user=root)
+connect (con1,localhost,root,,);
+# Con1 - Should see 'D'
+BEGIN;
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = 'D';
+
+--echo # Use default client to commit an update;
+--echo # Change the field value to 'A'
+connection default;
+UPDATE t2 SET f1 = 'A';
+
+--echo # Establish connection con2 (user=root)
+connect (con2,localhost,root,,);
+# Con2 - Should see 'A'
+BEGIN;
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = 'A';
+
+--echo # Use default client to commit an update;
+--echo # Change the field value back to 'B'
+--echo # and then 'C' in a second savepoint, then commit.
+connection default;
+BEGIN;
+UPDATE t2 SET f1 = 'B';
+SAVEPOINT sp1;
+UPDATE t2 SET f1 = 'C';
+RELEASE SAVEPOINT sp1;
+COMMIT;
+
+--echo # Establish connection con3 (user=root)
+connect (con3,localhost,root,,);
+# Con3 - Should see 'C'
+BEGIN;
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = 'C';
+
+--echo # Use default client to update value back to '-'
+connection default;
+UPDATE t2 SET f1 = '-';
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = '-';
+
+--echo # There now two record versions with 'A' & 'C'
+--echo # This update should cause a scavenge to prune old records.
+UPDATE t1 SET a = repeat('a',1000);
+
+# con1 - Should still see 'D'
+connection con1;
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = 'D';
+COMMIT;
+
+# con2 - Should still see 'A'
+connection con2;
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = 'A';
+COMMIT;
+
+# con3 - Should see 'C'
+connection con3;
+SELECT * FROM t2;
+SELECT * FROM t2 WHERE f1 = 'C';
+COMMIT;
+
+# con1 - Should still see 'D'
+connection con1;
+COMMIT;
+
+# con2 - Should still see 'A'
+connection con2;
+COMMIT;
+
+# con3 - Should see 'C'
+connection con3;
+COMMIT;
+
+connection default;
+disconnect con1;
+disconnect con2;
+disconnect con3;
+
+DROP TABLE t1, t2;