List:Commits« Previous MessageNext Message »
From:kevin.lewis Date:July 8 2011 1:17pm
Subject:bzr commit into mysql-5.5 branch (kevin.lewis:3457) Bug#12637786
View as plain text  
#At file:///Users/kevinlewis/Work/Mysql/12637786/mysql-5.5/ based on revid:joerg.bruehe@stripped

 3457 kevin.lewis@stripped	2011-07-08 [merge]
      Null Merge from mysql-5.1 with second fix for Bug#12637786
      
      Bug#12637786 was fixed with rb:692 by marko.  But that fix has a remaining
      bug.  It added this assert;
          ut_ad(ind_field->prefix_len);
      before a section of code that assumes there is a prefix_len.  
      
      The patch replaced code that explicitly avoided this with a check for
      prefix_len.  It turns out that the purge thread can get to that assert
      without a prefix_len because it does not use a row_ext_t* .
      When UNIV_DEBUG is not defined, the affect of this is that the purge thread
      sets the dfield->len to zero and then cannot find the entry in the index to
      purge.  So secondary index entries remain unpurged.
      
      This patch does not do the assert.  Instead, it uses
          'if (ind_field->prefix_len) {...}'
      around the section of code that assumes a prefix_len.  This is the way the
      patch I provided to Marko did it.
      
      The test case is simply modified to do a sleep(10) in order to give the
      purge thread a chance to run. Without the code change to row0row.c, this
      modified testcase will assert if InnoDB was compiled with UNIV_DEBUG.
      I tried to sleep(5), but it did not always assert.

    modified:
      mysql-test/suite/innodb/r/innodb-index.result
      mysql-test/suite/innodb/t/innodb-index.test
      storage/innobase/row/row0row.c
=== modified file 'mysql-test/suite/innodb/r/innodb-index.result'
--- a/mysql-test/suite/innodb/r/innodb-index.result	revid:joerg.bruehe@stripped
+++ b/mysql-test/suite/innodb/r/innodb-index.result	revid:kevin.lewis@stripped
@@ -973,6 +973,7 @@ v16 VARCHAR(500), v17 VARCHAR(500), v18 
 CREATE INDEX idx1 ON t1(a,v1);
 INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
 UPDATE t1 SET a=1000;
+DELETE FROM t1;
 DROP TABLE t1;
 set global innodb_file_per_table=0;
 set global innodb_file_format=Antelope;

=== modified file 'mysql-test/suite/innodb/t/innodb-index.test'
--- a/mysql-test/suite/innodb/t/innodb-index.test	revid:joerg.bruehe@stripped
+++ b/mysql-test/suite/innodb/t/innodb-index.test	revid:kevin.lewis@stripped
@@ -472,6 +472,9 @@ CREATE TABLE t1(a INT,
 CREATE INDEX idx1 ON t1(a,v1);
 INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
 UPDATE t1 SET a=1000;
+DELETE FROM t1;
+# Let the purge thread clean up this file.
+-- sleep 10
 DROP TABLE t1;
 
 eval set global innodb_file_per_table=$per_table;

=== modified file 'storage/innobase/row/row0row.c'
--- a/storage/innobase/row/row0row.c	revid:joerg.bruehe@stripped
+++ b/storage/innobase/row/row0row.c	revid:kevin.lewis@stripped
@@ -148,22 +148,27 @@ row_build_index_entry(
 				continue;
 			}
 		} else if (dfield_is_ext(dfield)) {
-			/* This table should be in Antelope format
-			(ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT).
-			In that format, the maximum column prefix
+			/* This table is either in Antelope format
+			(ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT)
+			or a purge record where the ordered part of
+			the field is not external.
+			In Antelope, the maximum column prefix
 			index length is 767 bytes, and the clustered
 			index record contains a 768-byte prefix of
 			each off-page column. */
 			ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
 			len -= BTR_EXTERN_FIELD_REF_SIZE;
+			dfield_set_len(dfield, len);
 		}
 
 		/* If a column prefix index, take only the prefix. */
-		ut_ad(ind_field->prefix_len);
-		len = dtype_get_at_most_n_mbchars(
-			col->prtype, col->mbminmaxlen,
-			ind_field->prefix_len, len, dfield_get_data(dfield));
-		dfield_set_len(dfield, len);
+		if (ind_field->prefix_len) {
+			len = dtype_get_at_most_n_mbchars(
+				col->prtype, col->mbminmaxlen,
+				ind_field->prefix_len, len,
+				dfield_get_data(dfield));
+			dfield_set_len(dfield, len);
+		}
 	}
 
 	ut_ad(dtuple_check_typed(entry));

No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
Thread
bzr commit into mysql-5.5 branch (kevin.lewis:3457) Bug#12637786kevin.lewis10 Jul