diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index aacaff30898..3ffefd2aedb 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12823,3 +12823,22 @@ a b c d e f -1 b c d e 1 DROP TABLE t1; SET sort_buffer_size=DEFAULT; +# +# BUG#11758979 - 51252: ARCHIVE TABLES STILL FAIL UNDER STRESS +# TESTS: CRASH, CORRUPTION, 4G MEMOR +# (to be executed with valgrind) +CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(NULL, ''); +FLUSH TABLE t1; +# we need this select to workaround BUG#11764364 +SELECT * FROM t1; +a b +NULL +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 286155052 +FLUSH TABLE t1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 4686b3ca1dc..3c18152ccc6 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1745,3 +1745,18 @@ INSERT INTO t1 SELECT t1.* FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6; SELECT * FROM t1 ORDER BY f LIMIT 1; DROP TABLE t1; SET sort_buffer_size=DEFAULT; + + +--echo # +--echo # BUG#11758979 - 51252: ARCHIVE TABLES STILL FAIL UNDER STRESS +--echo # TESTS: CRASH, CORRUPTION, 4G MEMOR +--echo # (to be executed with valgrind) +CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(NULL, ''); +FLUSH TABLE t1; +--echo # we need this select to workaround BUG#11764364 +SELECT * FROM t1; +CHECKSUM TABLE t1 EXTENDED; +FLUSH TABLE t1; +OPTIMIZE TABLE t1; +DROP TABLE t1; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 345c1b6835f..b6947688768 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -819,6 +819,7 @@ uint32 ha_archive::max_row_length(const uchar *buf) ptr != end ; ptr++) { + if (!table->field[*ptr]->is_null()) length += 2 + ((Field_blob*)table->field[*ptr])->get_length(); } @@ -1178,6 +1179,17 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record) /* Copy null bits */ const uchar *ptr= record_buffer->buffer; + /* + Field::unpack() is not called when field is NULL. For VARCHAR + Field::unpack() only unpacks as much bytes as occupied by field + value. In these cases respective memory area on record buffer is + not initialized. + + These uninitialized areas may be accessed by CHECKSUM TABLE or + by optimizer using temporary table (BUG#12997905). We may remove + this memset() when they're fixed. + */ + memset(record, 0, table->s->reclength); memcpy(record, ptr, table->s->null_bytes); ptr+= table->s->null_bytes; for (Field **field=table->field ; *field ; field++)