Skip to content

Commit 1f844fa

Browse files
author
kevin.lewis@oracle.com
committed
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.
2 parents 61eb98d + e3fab62 commit 1f844fa

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

mysql-test/suite/innodb/r/innodb-index.result

+1
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
973973
CREATE INDEX idx1 ON t1(a,v1);
974974
INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
975975
UPDATE t1 SET a=1000;
976+
DELETE FROM t1;
976977
DROP TABLE t1;
977978
set global innodb_file_per_table=0;
978979
set global innodb_file_format=Antelope;

mysql-test/suite/innodb/t/innodb-index.test

+3
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,9 @@ CREATE TABLE t1(a INT,
472472
CREATE INDEX idx1 ON t1(a,v1);
473473
INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
474474
UPDATE t1 SET a=1000;
475+
DELETE FROM t1;
476+
# Let the purge thread clean up this file.
477+
-- sleep 10
475478
DROP TABLE t1;
476479

477480
eval set global innodb_file_per_table=$per_table;

storage/innobase/row/row0row.c

+13-8
Original file line numberDiff line numberDiff line change
@@ -148,22 +148,27 @@ row_build_index_entry(
148148
continue;
149149
}
150150
} else if (dfield_is_ext(dfield)) {
151-
/* This table should be in Antelope format
152-
(ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT).
153-
In that format, the maximum column prefix
151+
/* This table is either in Antelope format
152+
(ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT)
153+
or a purge record where the ordered part of
154+
the field is not external.
155+
In Antelope, the maximum column prefix
154156
index length is 767 bytes, and the clustered
155157
index record contains a 768-byte prefix of
156158
each off-page column. */
157159
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
158160
len -= BTR_EXTERN_FIELD_REF_SIZE;
161+
dfield_set_len(dfield, len);
159162
}
160163

161164
/* If a column prefix index, take only the prefix. */
162-
ut_ad(ind_field->prefix_len);
163-
len = dtype_get_at_most_n_mbchars(
164-
col->prtype, col->mbminmaxlen,
165-
ind_field->prefix_len, len, dfield_get_data(dfield));
166-
dfield_set_len(dfield, len);
165+
if (ind_field->prefix_len) {
166+
len = dtype_get_at_most_n_mbchars(
167+
col->prtype, col->mbminmaxlen,
168+
ind_field->prefix_len, len,
169+
dfield_get_data(dfield));
170+
dfield_set_len(dfield, len);
171+
}
167172
}
168173

169174
ut_ad(dtuple_check_typed(entry));

0 commit comments

Comments
 (0)